I was working on an application that makes quite a few requests using the HttpWebRequest
class to bring back data from the web. Now my app makes nearly identical calls in multiple parts of my application. This is turning into a problem because I'm duplicating a lot of code.
The ideal solution would be to encapsulate the logic that makes the calls to the web in it's own class that way updating is a breeze and it can be reused throughout my application. I'm just not sure how to make an asynchronous call in a separate class and return the value to my main code behind so I can update the UI with the data.
Can someone provide me with some guidance on how to make this happen? I know this has to be pos开发者_如何学Pythonsible because developers are doing it all the time when following the MVVM pattern.
I'm using Silverlight/C#.
We have code like this in our Silverlight app for use with WCF Data Services. You could probably do something similar for your web requests:
Here is some sample code (untested) (note that I have not actually ever written any code that does web requests, but maybe the async pattern is similar to other stuff that I have done in Silverlight):
public class WebRequesterHelper
{
Action _callback;
public void MakeWebRequest(object whateverYouNeedForTheWebRequest, Action callback)
{
_callback = callback;
//Make your async web request here, passing the helper object's callback.
IAsyncResult result = yourWebRequestObject.BeginGetResponse(new AsyncResultCallback(WebRequestCallback), yourRequestState);
}
public void WebRequestCallback(IAsyncResult result)
{
//Do whatever you need to do as a result of the web request, then call the callback.
if (_callback != null) callback();
}
}
In your code that wants to make a web request:
var helper = new WebRequestHelper();
//Setup the web request
object request = SetUpYourWebRequest();
helper.MakeWebRequest(request, OnWebRequestCompleted);
Your helper callback:
public void OnWebRequestCompleted()
{
//Web request is finished, what do I want to do?
}
Note that you might want your callback (which you pass to the WebRequestHelper object) to accept a parameter and you could pass information back out from the web request callback function (in the WebRequestHelper object).
Since your web download code is effectively your business logic I would definitely encapsulate it in it's own class as you planned. Then you should use events to notify your UI of state changes.
For example, your "WebRequestManager" instance can encapsulate all the thread handling and will raise events to allow the UI to respond accordingly. You would raise an event on TaskCompleted
and perhaps also at intervals to provide looking feedback such as AsyncProgressChanged
.
NOTE: By way of convention, I would tend to prefix any events that are likely going to be called from a thread other than the original calling one with the name "Async" so that the UI handler knows to join back onto the UI thread.
精彩评论