In the previous posts, I have explained about the Sharing and Receiving data.
1. http://blogs.msdn.com/b/going_metro/archive/2012/05/02/integrating-with-windows-8-share-charm-part-1-sharing-data.aspx2. http://blogs.msdn.com/b/going_metro/archive/2012/05/03/integrating-with-windows-8-share-charm-part-1-receiving-data.aspx
In this post, I will discuss the concept of Long Running Shares, using a sample App called "Bing Images" .
The Bing Images app can be used to search for images. In the previous posts I wrote code to share the Uri of the image. I am going to implement functionality to be able to share the image along with the Url.
Following is the code, I used to share the image .
When I run the app and try to share the image, Win RT displays the message "Images Can't Share" as shown below.
Why is this ?
This is because of the code we added to download the image for sharing. Note that we are using asynchronous methods and also using the "await" keyword to download the image.
When the execution reaches an awaited asynchronous call which is not yet complete, it returns at that point. In our case, the method "Data Requested" handler returns before setting the contents of the data package, hence the message.
However WinRT supports asynchronous sharing operations, by creating a Deferral (DataRequestDeferral) and waiting for it to complete. I modified my code, to obtain a deferral using the "DataRequest.GetDeferral" method and to call the "DataRequestDeferral.Complete" method once data content for the asynchronous share is ready.
Now when we will be able to share the data with other apps.
Note : This method will only work if the asynchronous operation completes within 200 mill seconds.
In our case, some of the images were taking more than 200 mill seconds to download, and in those cases Sharing failed. WinRT provides another mechanism for handling such situations using a delegate (callback method).
We can define a call back delegate using the "SetDataProvider" method.
Once the target app is selected in the sharing pane, the target app calls the Callback method.
Within the callback method, I added the asynchronous download code.
Note: We still have to acquire a "Deferral" within the Callback method, and call the Complete method once the data is set
It got me thinking, why is this. In both the methods we acquired a deferral, but in the first method the asynchronous call should complete with-in 200 milli-seconds, but in the case of call back scenario, we do not have this restriction (200 MS). The secret lies in the DataRequest objects "Deadline" property.
In both the scenario's I have set a break point and observed the DeadLine property.
In first scenario, the Deadline (In our ex: it is 4:35:10) and the time at which sharing is initiated (In our ex it is 4:35:10), is the same to the second. This explains the 200 milli seconds restriction.
In the second scenario (Callback), the requests Deadline is set to approximately 6 minutes from the time the call back is initiated. In our example, the callback was initiated at 4:39:10, but the deadline was set to 4:45 (6 minutes).
So even in the case of the Callback, there is a limitation (from my experimentation, it is around 6 minutes). I think this is a good enough time for any share operations that I could think of.
Hope this helps.