/// <summary> /// Initializes the source in order to obtain a random sequence. /// </summary> public void InitializeNonRepeatable() { // Get a random sequence Id (capped to the maximum number it can reach) Random r = new Random(); int rndId = r.Next(maximumSequenceId + 1); // Find out the effective numbers of values in the file string filePath = Path.Combine(this.defaultPath, "RngSequence" + rndId.ToString()); long numbersCount = 0; if (File.Exists(filePath)) { using (FileStream stream = new FileStream(filePath, FileMode.Open)) { numbersCount = stream.Length; } } numbersCount /= sizeof(double); if (numbersCount == 0) { // If there are no numbers in the file initialize the sequence from the start InitializeRepeatable(rndId); } else { // Otherwise initialize it from a random position (valid for the given file) double d = r.NextDouble(); long rndPosition = (long)(d * numbersCount); QrngWebserviceRestorePoint rp = new QrngWebserviceRestorePoint(rndId, rndPosition); Connect(); LoadState(rp); } }
/// <summary> /// Restore the state of the source based on the given object. /// </summary> /// <param name="restorePoint">The restore point.</param> public void LoadState(IRandomGeneratorRestorePoint restorePoint) { QrngWebserviceRestorePoint rp = restorePoint as QrngWebserviceRestorePoint; if (rp == null) { return; } // If the data is still being loaded on the background thread wait for it to end // and set it to null if (this.loadingThread != null) { this.loadingThread.Join(); this.loadingThread = null; } // Set the starting Id and position this.startingSequenceId = rp.SequenceId; this.position = rp.Position; // Calculate the state parameters int unadjustedBlockNo = (int)(rp.Position / numbersPerBlock); int sequenceOffset = this.currentBlock / (maximumNumbersPerFile / numbersPerBlock); this.sequenceId = this.startingSequenceId + sequenceOffset; this.currentBlock = unadjustedBlockNo % (maximumNumbersPerFile / numbersPerBlock); this.currentIndex = (int)(this.position - (unadjustedBlockNo * numbersPerBlock)); // Load the buffers (the first synchronously, the second asynchronously) LoadRngNumbers(this.currentBlock, 0); this.currentBufferIndex = 0; if (!double.IsNaN(this.buffers[0][0])) { DownloadBlockAsynchronous(1); } }