同步方法中的异步开始/结束

use*_*117 0 c# asynchronous

(我正在使用.Net 4.0)

我想从我的服务层异步调用WCF服务.此服务层由MVC.Net控制器使用.我已经读过,异步调用WCF服务是一种很好的做法.所以我正在使用begin/end(apm).我想仔细检查我是否做得很丰富:

public byte[] GetSomeData()
{
    IAsyncResult result = myServiceClient.BeginDoSomething(someInputValue, null, null);

    var data = _pdfCreatieService.EndCreateForPreview(result);

    return data;
}
Run Code Online (Sandbox Code Playgroud)

我不完全确定上面的代码,因为我已经看到了类似下面代码的构造,在我的情况下看起来有点复杂和不必要:

public byte[] GetSomeData()
{
    var myState = new MyState();

    IAsyncResult result = _myServiceClient.BeginDoSomething(someInputValue, CreateForPreviewCallback, myState);

    result.AsyncWaitHandle.WaitOne();

    return myState.Bytes;
}

private void DoSomethingCallback(IAsyncResult result)
{
    var myState = (MyState)result.AsyncState;

    myState.Bytes = _myServiceClient.EndDoSomething(result);
}
Run Code Online (Sandbox Code Playgroud)

感谢Avner Shahar-Kashtan,Ned Stoyanov和Noseratio.你的答案非常有见地!

Avn*_*tan 5

实际上,您的代码将采用异步方法并同步调用它.当您调用该EndDoSomething方法时,您实际上会阻塞您的线程,直到异步方法完成,这与异步调用完全相反.

当然,您的第二个代码块也会通过使用waithandle显式阻止执行来同步调用代码.

你想要做的是,不是byte[]从你的初始方法返回,而是让你DoSomethingCallback对字节做一些活动 - 将它们存储在一些可以由控制器检查,引发事件或做其他事情的类成员中.如果您正在等待异步呼叫,则无法获得任何好处.

如果您使用的是.NET 4.5或更高版本(或VS2012中的.NET 4.0,使用BCL异步包),您还可以使用async/await,这是一个很好的包装器,它允许您合并调用方法和回调方法分为单一,更连贯的方法.

但无论您选择哪种语法或库,您的第一步是了解异步编程必然会将代码的控制流分解为调用和结果回调,或者继续异步操作.