public void Unload()
 {
     lock (_syncLock)
     {
         _alreadyRetrieved = false;
         _framePixelData   = null;
         ResetAttemptData();
     }
 }
            public byte[] GetUncompressedPixelData(out string photometricInterpretation)
            {
                try
                {
                    //construct this object before the lock so there's no chance of deadlocking
                    //with the parent data source (because we are accessing its tags at the
                    //same time as it's trying to get the pixel data).
                    var retriever = new FramePixelDataRetriever(this);

                    lock (_syncLock)
                    {
                        IFramePixelData framePixelData;

                        if (_framePixelData == null)
                        {
                            AbortAttemptIfNecessary();

                            ResetAttemptData();
                            _retrievesAttempted++;

                            framePixelData = retriever.Retrieve();
                        }
                        else
                        {
                            framePixelData = _framePixelData;
                        }

                        //free this memory up in case it's holding a compressed buffer.
                        _framePixelData = null;

                        var clock = new CodeClock();
                        clock.Start();

                        //synchronize the call to decompress; it's really already synchronized by
                        //the parent b/c it's only called from CreateFrameNormalizedPixelData, but it doesn't hurt.
                        byte[] pixelData = framePixelData.GetPixelData(out photometricInterpretation);

                        clock.Stop();

                        Platform.Log(LogLevel.Debug,
                                     "[Decompress Info] Sop/Frame: {0}/{1}, Transfer Syntax: {2}, Uncompressed bytes: {3}, Elapsed (s): {4}",
                                     retriever.SopInstanceUid, FrameNumber, retriever.TransferSyntaxUid,
                                     pixelData.Length, clock.Seconds);

                        return(pixelData);
                    }
                }
                catch (Exception ex)
                {
                    _lastError = ex;
                    throw;
                }
            }
            public void Retrieve()
            {
                if (!_alreadyRetrieved)
                {
                    //construct this object before the lock so there's no chance of deadlocking
                    //with the parent data source (because we are accessing it's tags at the
                    //same time as it's trying to get the pixel data).
                    var retriever = new FramePixelDataRetriever(this);

                    lock (_syncLock)
                    {
                        if (!_alreadyRetrieved)
                        {
                            AbortAttemptIfNecessary();

                            try
                            {
                                ResetAttemptData();
                                _retrievesAttempted++;
                                var start = DateTime.Now;
                                _framePixelData = retriever.Retrieve();
                                var end = DateTime.Now;
                                _lastRetrievePerformanceInfo =
                                    new StreamingPerformanceInfo(start, end, _framePixelData.BytesReceived);

                                _alreadyRetrieved = true;
                            }
                            catch (Exception ex)
                            {
                                _lastError = ex;
                                throw;
                            }
                        }
                    }
                }
            }
            private IFramePixelData TryClientRetrievePixelData(out Exception lastRetrieveException)
            {
                // retry parameters
                const int maxRetryCount = 10;
                const int retryTimeout  = 1500;
                int       retryDelay    = 50;
                int       retryCounter  = 0;

                IFramePixelData result = null;

                lastRetrieveException = null;

                var timeoutClock = new CodeClock();

                timeoutClock.Start();

                while (true)
                {
                    try
                    {
                        if (retryCounter > 0)
                        {
                            Platform.Log(LogLevel.Info, "Retrying retrieve pixel data for Sop '{0}' (Attempt #{1})", this.SopInstanceUid, retryCounter);
                        }

                        CodeClock statsClock = new CodeClock();
                        statsClock.Start();

                        result = _loader.LoadFramePixelData(new LoadSopFramePixelDataArgs(this._frameNumber));

                        statsClock.Stop();

                        Platform.Log(LogLevel.Debug, "[Retrieve Info] Sop/Frame: {0}/{1}, Transfer Syntax: {2}, Bytes transferred: {3}, Elapsed (s): {4}, Retries: {5}",
                                     this.SopInstanceUid, this._frameNumber, this.TransferSyntaxUid,
                                     result.BytesReceived, statsClock.Seconds, retryCounter);

                        break;
                    }
                    catch (Exception ex)
                    {
                        lastRetrieveException = ex;

                        timeoutClock.Stop();
                        if (timeoutClock.Seconds * 1000 >= retryTimeout || retryCounter >= maxRetryCount)
                        {
                            // log an alert that we are aborting (exception trace at debug level only)
                            int elapsed = (int)(1000 * timeoutClock.Seconds);
                            Platform.Log(LogLevel.Warn, "Failed to retrieve pixel data for Sop '{0}'; Aborting after {1} attempts in {2} ms", this.SopInstanceUid, retryCounter, elapsed);
                            Platform.Log(LogLevel.Debug, ex, "[Retrieve Fail-Abort] Sop/Frame: {0}/{1}, Retry Attempts: {2}, Elapsed: {3} ms", this.SopInstanceUid, this._frameNumber - 1, retryCounter,
                                         elapsed);
                            break;
                        }
                        timeoutClock.Start();

                        retryCounter++;

                        // log the retry (exception trace at debug level only)
                        Platform.Log(LogLevel.Warn, "Failed to retrieve pixel data for Sop '{0}'; Retrying in {1} ms", this.SopInstanceUid, retryDelay);
                        Platform.Log(LogLevel.Debug, ex, "[Retrieve Fail-Retry] Sop/Frame: {0}/{1}, Retry in: {2} ms", this.SopInstanceUid, this._frameNumber - 1, retryDelay);
                        MemoryManager.Collect(retryDelay);
                        retryDelay *= 2;

                        if (retryDelay > MaxRetryDelay)
                        {
                            retryDelay = MaxRetryDelay;                             // cap it to avoid overflow, which will cause exception when calling MemoryManager.Collect()
                        }
                    }
                }

                return(result);
            }
			public void Unload()
			{
				lock (_syncLock)
				{
					_alreadyRetrieved = false;
					_framePixelData = null;
					ResetAttemptData();
				}
			}
			public byte[] GetUncompressedPixelData(out string photometricInterpretation)
			{
				try
				{

					//construct this object before the lock so there's no chance of deadlocking
					//with the parent data source (because we are accessing its tags at the 
					//same time as it's trying to get the pixel data).
					var retriever = new FramePixelDataRetriever(this);

					lock (_syncLock)
					{
						IFramePixelData framePixelData;

						if (_framePixelData == null)
						{
							AbortAttemptIfNecessary();

							ResetAttemptData();
							_retrievesAttempted++;

							framePixelData = retriever.Retrieve();
						}
						else
							framePixelData = _framePixelData;

						//free this memory up in case it's holding a compressed buffer.
						_framePixelData = null;

						var clock = new CodeClock();
						clock.Start();

						//synchronize the call to decompress; it's really already synchronized by
						//the parent b/c it's only called from CreateFrameNormalizedPixelData, but it doesn't hurt.
						byte[] pixelData = framePixelData.GetPixelData(out photometricInterpretation);

						clock.Stop();

						Platform.Log(LogLevel.Debug,
						             "[Decompress Info] Sop/Frame: {0}/{1}, Transfer Syntax: {2}, Uncompressed bytes: {3}, Elapsed (s): {4}",
						             retriever.SopInstanceUid, FrameNumber, retriever.TransferSyntaxUid,
						             pixelData.Length, clock.Seconds);

						return pixelData;
					}
				}
				catch (Exception ex)
				{
					_lastError = ex;
					throw;
				}
			}
			public void Retrieve()
			{
				if (!_alreadyRetrieved)
				{
					//construct this object before the lock so there's no chance of deadlocking
					//with the parent data source (because we are accessing it's tags at the 
					//same time as it's trying to get the pixel data).
					var retriever = new FramePixelDataRetriever(this);

					lock (_syncLock)
					{
						if (!_alreadyRetrieved)
						{
							AbortAttemptIfNecessary();

							try
							{
								ResetAttemptData();
								_retrievesAttempted++;
								var start = DateTime.Now;
								_framePixelData = retriever.Retrieve();
								var end = DateTime.Now;
								_lastRetrievePerformanceInfo =
									new StreamingPerformanceInfo(start, end, _framePixelData.BytesReceived);

								_alreadyRetrieved = true;
							}
							catch (Exception ex)
							{
								_lastError = ex;
								throw;
							}
						}
					}
				}
			}