我可以通过使用事件来创建我的AsyncResult来快捷开始/结束异步模式吗?

时间:2010-11-19 19:12:11

标签: c# .net wcf events asynchronous

我想为我的WCF服务轻松创建异步方法。我知道这样做的方法是使用Begin / End异步模式,并使用AsyncPattern = true标记Begin方法。我想知道我是否真的需要让自己的AsyncResult对象来处理(我有点紧张)或者我是否可以使用事件处理程序并基本上将我的Begin / End包装在事件处理程序的Begin / End调用周围。这似乎是一种圆满的方式,但是因为(据我所知)我无法直接从WCF订阅或调用事件,这似乎是一个看似合理的解决方案。

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);
}

然后,显然,某事订阅了该事件来完成这项工作。我也丢弃了传入Begin方法的对象状态,支持将事件处理程序作为状态传递,因此我可以访问它来调用EndInvoke。

这是一个可行的选择吗? (我对AsyncResult对象和异步编程如何工作的知识和理解有限。)

2 个答案:

答案 0 :(得分:0)

Checkout .NET的反应性扩展(Rx)。这是您正在寻找的模式的an implementation

鉴于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
    });

答案 1 :(得分:0)

是的我用开始/结束模式做同样的事情。它看起来像这样:

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);
}