异步CTP - 如何使用async/await来调用wcf服务?

Rog*_*ger 15 c# asynchronous async-await

如果我调用WCF服务方法,我会做这样的事情:

proxy.DoSomethingAsync();
proxy.DoSomethingAsyncCompleted += OnDoSomethingAsyncCompleted;
Run Code Online (Sandbox Code Playgroud)

我怎么能用新的asyncctp 做同样的事情?我想我会需要这样的东西proxy.DoSomethingTaskAsync还是proxy.DoSomethingAsync().ToTask()?Web服务调用需要返回一个Task<T>能够使用await关键字,但如何?

Mat*_*ren 10

在CTP中,有工厂方法可以将常规APM功能(开始/结束)转换为与新的async关键字兼容的工作方法,例如:

Stream s = new FileStream("C:\test.txt", FileMode.CreateNew);
byte []buffer = new byte[100];
int numBytesRead = await Task<int>.Factory.FromAsync(s.BeginRead, s.EndRead, buffer, 0, buffer.Length, null);
Run Code Online (Sandbox Code Playgroud)

所以在你的情况下,你可以做相同的,然后你会这样称呼它:

async proxy.DoSomethingTaskAsync()
Run Code Online (Sandbox Code Playgroud)

有关详细信息,请参阅CTP讨论组中的此主题


Ste*_*ter 6

使用async-await的异步服务非常敏感,因为它可以交错许多客户端调用并并行执行它们(2).尽管如此,该服务可以在一个线程(3)上完全运行线程安全,并且可以是单例服务(1)或由框架为会话或仅调用创建的服务对象.

在实施服务时,请注意ServiceBehaviourAttributes(1)...(3):

    [ServiceContract( Namespace="X", Name="TheContract" )]
    public interface IAsyncContractForClientAndService
    {
        [OperationContract]
        Task<TResponse> SendReceiveAsync( TRequest req );
    }



    [ServiceBehavior (InstanceContextMode = InstanceContextMode.Single, // (1)
                      // also works with InstanceContextMode.PerSession or PerCall
                      ConcurrencyMode     = ConcurrencyMode.Multiple,   // (2)
                      UseSynchronizationContext = true)]                // (3)

    public MyService : IAsyncContractForClientAndService
    {
        public async Task<TResponse> SendReceiveAsync( TRequest req )
        {
            DoSomethingSynchronous();
            await SomethingAsynchronous(); 
            // await lets other clients call the service here or at any await in
            // subfunctions. Calls from clients execute 'interleaved'.
            return new TResponse( ... );
        }
    }
Run Code Online (Sandbox Code Playgroud)

要在一个线程上运行每个调用,在Open()ServiceHost时必须存在System.Threading.SynchronizationContext.Current!= null.使用SynchronizationContext,您无需关心锁.原子的,不可中断的代码段大致从一个等待到下一个.注意共享服务数据在每次等待时都处于一致状态,并注意来自一个客户端的连续请求可能不按它们发送的顺序进行响应.

在客户端,异步服务操作是等待的:

   var response = await client.Channel.SendReceiveAsync( request );
Run Code Online (Sandbox Code Playgroud)

在操作合同中不可能使用outref参数.所有响应数据必须由返回值Task(T)传递.
我在AsyncWcfLib中使用这个接口,它支持基于Actor的编程模型.