Can I shortcut the Begin/End async pattern by using an event to create my AsyncResult?
I would like to easily create asynchronous methods for my WCF service. I know the way to do this is to use the Begin/End async pattern, and labeling my Begin method with AsyncPattern=true. I'm wondering if I really need to make my own AsyncResult object to handle (which I'm a bit nervous about doing) or if I can use an event handler and essentially wrap my Begin/End around the event handler's Begin/End invoke. This seems like a round-about way of doing this, but开发者_如何学编程 since (as far as I know) I can't subscribe or invoke the event directly from WCF it seems like a plausible solution.
private event EventHandler<RequestEventArgs> OnSendRequest;
[OperationContract(AsyncPattern = true)] // Borrowed from the interface for this example
public IAsyncResult BeginSendRequest(Request request, AsyncCallback callback, object state)
{
EventHandler<RequestEventArgs> handler = OnSendRequest;
if (handler != null)
return handler.BeginInvoke(this, new RequestEventArgs(request), callback, handler);
return null;
}
public void EndSendRequest(IAsyncResult result)
{
EventHandler<RequestEventArgs> handler = (EventHandler<RequestEventArgs>)result.AsyncState;
handler.EndInvoke(result);
}
Then, obviously, something subscribes to the event to do the work. I'm also throwing away the object state passed in to my Begin method, in favor of passing the event handler as the state so I have access to it to call EndInvoke.
Is this a viable option? (I have limited knowledge and understanding of how the AsyncResult object and asynchronous programming in general work.)
Yes I am doing the same thing with the begin / end pattern. It looks like this:
public IAsyncResult BeginInsertWorkOrder(Dictionary<String, String> workOrderData, AsyncCallback callBack, Object state)
{
Action<Dictionary<String, String>> command = new Action<Dictionary<String, String>>(InsertWorkOrder);
return command.BeginInvoke(workOrderData, callBack, command);
}
Checkout Reactive Extensions for .NET (Rx). This is an implementation of the pattern that you are looking for.
Given example:
var client = new WebClient();
var searchUri = new Uri("http://search.twitter.com/search.json?q=4sq.com");
var uploadUri = new Uri("http://localhost:8080/uploads");
IObservable<Unit> query =
from result in client.DownloadStringAsObservable(searchUri, new object())
let transformed = TransformResult(result)
from upload in client.UploadStringAsObservable(
uploadUri,
"POST",
transformed,
new object())
select upload;
var subscription = query.Subscribe(
x => {}, // Nothing to do
exn =>
{
// Do something with the exception
},
() =>
{
// Indicate we're finished
});
精彩评论