/// <summary> /// takes a given feed, and does a batch post of that feed /// against the batchUri parameter. If that one is NULL /// it will try to use the batch link URI in the feed /// </summary> /// <param name="feed">the feed to post</param> /// <param name="batchUri">the URI to user</param> /// <param name="userData">the userdata identifying this request</param> /// <returns></returns> public void BatchAsync(AtomFeed feed, Uri batchUri, Object userData) { AsyncSendData data = new AsyncSendData(this, batchUri, feed, this.ProgressReportDelegate, userData); WorkerSendEventHandler workerDelegate = new WorkerSendEventHandler(AsyncBatchWorker); this.AsyncStarter(data, workerDelegate, userData); }
/// <summary> /// inserts the entry asynchronous, you need to supply a valid and unique /// token. Events will be send to the async delegates you setup on the service /// object /// </summary> /// <param name="feedUri">the target feed the entry get's inserted into</param> /// <param name="entry"></param> /// <param name="userData">a unique identifier to associate this request with</param> /// <returns></returns> public void InsertAsync(Uri feedUri, AtomEntry entry, Object userData) { AsyncSendData data = new AsyncSendData(this, feedUri, entry, this.ProgressReportDelegate, userData); WorkerSendEventHandler workerDelegate = new WorkerSendEventHandler(AsyncInsertWorker); this.AsyncStarter(data, workerDelegate, userData); }
/// <summary> /// updates the entry asynchronous, you need to supply a valid and unique /// token. Events will be send to the async delegates you setup on the service /// object /// </summary> /// <param name="entry"></param> /// <param name="userData">a unique identifier to associate this request with</param> /// <returns></returns> public void UpdateAsync(AtomEntry entry, Object userData) { AsyncSendData data = new AsyncSendData(this, entry, this.ProgressReportDelegate, userData); WorkerSendEventHandler workerDelegate = new WorkerSendEventHandler(AsyncUpdateWorker); this.AsyncStarter(data, workerDelegate, userData); }
/// <summary> /// this is a helper function for to send binary data asyncronous to a resource /// </summary> /// <param name="targetUri"></param> /// <param name="inputStream"></param> /// <param name="type"></param> /// <param name="contentType">the contenttype to use in the request, if NULL is passed, factory default is used</param> /// <param name="slugHeader">the slugHeader to use in the request, if NULL is passed, factory default is used</param> /// <param name="userData">a unique identifier to associate this request with</param> /// <param name="parseFeed">indicates if the async operation should try to parse the server returned stream, or just return the stream</param> /// <returns></returns> private void StreamSendAsync(Uri targetUri, Stream inputStream, GDataRequestType type, string contentType, string slugHeader, object userData, bool parseFeed) { AsyncSendData data = new AsyncSendData(this, targetUri, inputStream, type, contentType, slugHeader, this.ProgressReportDelegate, userData, parseFeed); WorkerSendEventHandler workerDelegate = new WorkerSendEventHandler(AsyncStreamSendWorker); this.AsyncStarter(data, workerDelegate, userData); }
/// <summary> /// worker method for the batch case /// </summary> /// <param name="data"></param> /// <param name="asyncOp"></param> /// <param name="completionMethodDelegate"></param> /// <returns></returns> private void AsyncBatchWorker(AsyncSendData data, AsyncOperation asyncOp, SendOrPostCallback completionMethodDelegate) { try { data.Feed = this.Batch(data.Feed, data.UriToUse, data); } catch (Exception e) { data.Exception = e; } completionMethodDelegate(data); }
/// <summary> /// worker method for the Insert case /// </summary> /// <param name="data"></param> /// <param name="asyncOp"></param> /// <param name="completionMethodDelegate"></param> /// <returns></returns> private void AsyncInsertWorker(AsyncSendData data, AsyncOperation asyncOp, SendOrPostCallback completionMethodDelegate) { try { data.Entry = this.Insert(data.UriToUse, data.Entry, data); } catch (Exception e) { data.Exception = e; } completionMethodDelegate(data); }
/// <summary> /// worker method for the direct stream send /// </summary> /// <param name="data"></param> /// <param name="asyncOp"></param> /// <param name="completionMethodDelegate"></param> /// <returns></returns> private void AsyncStreamSendWorker(AsyncSendData data, AsyncOperation asyncOp, SendOrPostCallback completionMethodDelegate) { try { using (var responseStream = StreamSend(data.UriToUse, data.DataStream, data.Type, data.ContentType, data.SlugHeader, null, data)) { HandleResponseStream(data, responseStream, -1); } } catch (Exception e) { data.Exception = e; } completionMethodDelegate(data); }
/// <summary> /// starts the async job /// </summary> /// <param name="data"></param> /// <param name="userData"></param> /// <param name="workerDelegate"></param> /// <returns></returns> private void AsyncStarter(AsyncSendData data, WorkerSendEventHandler workerDelegate, Object userData) { AsyncOperation asyncOp = AsyncOperationManager.CreateOperation(userData); data.Operation = asyncOp; AddUserDataToDictionary(userData, asyncOp); // Start the asynchronous operation. workerDelegate.BeginInvoke( data, asyncOp, this.CompletionMethodDelegate, null, null); }
///////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////// /// <summary>Inserts an AtomBase entry against a Uri. The overloaded /// version here will check if this is an AbstractEntry and if it has /// a media property set. If so, it will create a mime multipart envelope</summary> /// <param name="feedUri">the uri for the feed this object should be posted against</param> /// <param name="baseEntry">the entry to be inserted</param> /// <param name="type">the type of request to create</param> /// <param name="data">the async data payload</param> /// <returns> the response as a stream</returns> ////////////////////////////////////////////////////////////////////// internal override Stream EntrySend(Uri feedUri, AtomBase baseEntry, GDataRequestType type, AsyncSendData data) { if (feedUri == null) { throw new ArgumentNullException("feedUri"); } //Tracing.Assert(baseEntry != null, "baseEntry should not be null"); if (baseEntry == null) { throw new ArgumentNullException("baseEntry"); } AbstractEntry entry = baseEntry as AbstractEntry; // if the entry is not an abstractentry or if no media is set, do the default if (entry == null || entry.MediaSource == null) { return(base.EntrySend(feedUri, baseEntry, type, data)); } Stream outputStream = null; Stream inputStream = null; try { IGDataRequest request = this.RequestFactory.CreateRequest(type, feedUri); request.Credentials = this.Credentials; GDataRequest r = request as GDataRequest; if (r != null) { r.ContentType = MediaService.MimeContentType; r.Slug = entry.MediaSource.Name; GDataRequestFactory f = this.RequestFactory as GDataRequestFactory; if (f != null) { f.CustomHeaders.Add("MIME-version: 1.0"); } } if (data != null) { GDataGAuthRequest gr = request as GDataGAuthRequest; if (gr != null) { gr.AsyncData = data; } } outputStream = request.GetRequestStream(); inputStream = entry.MediaSource.GetDataStream(); StreamWriter w = new StreamWriter(outputStream); w.WriteLine("Media multipart posting"); CreateBoundary(w, GDataRequestFactory.DefaultContentType); baseEntry.SaveToXml(outputStream); w.WriteLine(); CreateBoundary(w, entry.MediaSource.ContentType); WriteInputStreamToRequest(inputStream, outputStream); w.WriteLine(); w.WriteLine("--" + MediaService.MimeBoundary + "--"); w.Flush(); request.Execute(); outputStream.Close(); outputStream = null; return(request.GetResponseStream()); } catch (Exception) { throw; } finally { if (outputStream != null) { outputStream.Close(); } if (inputStream != null) { inputStream.Close(); } } }