/// <summary> /// Write a data item into data container and flush /// </summary> /// <param name="data">data content to be written</param> public void AddDataAndFlush(DataContent data) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[BlobDataContainer] .AddDataAndFlush"); using (MemoryStream ms = new MemoryStream()) { // dump all data into a memory stream data.Dump(ms); // create timer that updates "CommonDataLastUpdateTime" metadata peoriodically Timer updateMetadataTimer = new Timer( this.MarkBlobAsBeingUploaded, null, TimeSpan.FromMilliseconds(Constant.LastUpdateTimeUpdateIntervalInMilliseconds), TimeSpan.FromMilliseconds(Constant.LastUpdateTimeUpdateIntervalInMilliseconds)); // write data Exception transferException = null; try { BlobTransferOptions transferOptions = new BlobTransferOptions { Concurrency = Environment.ProcessorCount * 8, }; using (BlobTransferManager transferManager = new BlobTransferManager(transferOptions)) { transferManager.QueueUpload( this.dataBlob, ms, null, delegate(object userData, double speed, double progress) { TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[BlobDataContainer] .AddDataAndFlush: progress={0}%", progress); }, delegate(object userData, Exception ex) { if (ex != null) { transferException = ex; } }, null); transferManager.WaitForCompletion(); } } finally { updateMetadataTimer.Dispose(); } TraceHelper.TraceSource.TraceEvent(TraceEventType.Verbose, 0, "[BlobDataContainer] .AddDataAndFlush: data transfer done"); DataException dataException = null; if (transferException != null) { dataException = TranslateTransferExceptionToDataException(transferException); } try { int errorCode = DataErrorCode.Success; string errorMessage = string.Empty; if (dataException != null) { errorCode = dataException.ErrorCode; errorMessage = dataException.Message; } AzureBlobHelper.MarkBlobAsCompleted(this.dataBlob, errorCode.ToString(), errorMessage); } catch (StorageException ex) { TraceHelper.TraceSource.TraceEvent( TraceEventType.Error, 0, "[BlobDataContainer] .AddDataAndFlush: failed to mark blob as completed. blob url={0}. error code={1}, exception={2}", this.dataBlob.Uri.AbsoluteUri, BurstUtility.GetStorageErrorCode(ex), ex); } catch (Exception ex) { TraceHelper.TraceSource.TraceEvent( TraceEventType.Error, 0, "[BlobDataContainer] .AddDataAndFlush: failed to mark blob as completed. blob url={0}. Exception={1}", this.dataBlob.Uri.AbsoluteUri, ex); } if (dataException != null) { throw dataException; } } }