在客户端和服务端应用异步等待的区别

3

我创建了一个WCF服务,其operationcontract和实现如下:

    [OperationContract]
    Task<string> GetName(string name);

   public async Task<string> GetName(string name)
    {
         await Task.Delay(5000);
         var task1 = Task<string>.Factory.StartNew(() =>
         {
             return "Your name is : " + name;
         });
         var result = await task1;
         return result;
        }

现在我正在客户端使用此服务,并创建了客户端。

 ServiceReference1.Service1Client client = new ServiceReference1.Service1Client();

我的实现中有两种方法:GetName和GetNameAsync。

我可以使用以下两种方式来访问该服务。

var result_GetName = await Task.Factory.StartNew(() => client.GetName("My Input"));
 var result_GetNameAsync = await client.GetNameAsync("My Input");
  • Q.1 这两种方法有什么区别吗?
  • Q.2 在特定情况下是否建议使用其中一种?还是我可以随时使用任何一种。
  • Q.3 对于第二次调用,我在两个地方(客户端-服务器)都使用了async-await,这样做有什么优势吗?

请指导。

1个回答

8
我不知道WCF生成的代码长什么样,但我认为第二种形式会更好。 (编辑:阅读 Stephen的博客文章以获取详细信息。)
第一种方法创建一个调用方法的新任务,以同步方式-阻塞线程直到方法返回。因此,如果您同时有许多这些调用,则最终会使用大量线程,从而使用内存。
我认为第二种方法会更加“本地”异步-基本上是发送请求,然后在返回时在潜在不同的线程上处理响应。
对于您的最后一个问题:

对于第二个调用,我在两个地方(客户端-服务器)使用了async-await,是否有任何优势?

您在两个片段中的await都使用了。但是,确实在两个地方使用异步代码有优势。在客户端中,可以节省客户端线程。在服务器端,可以节省服务器线程。
使用纯异步版本,您可以在客户端和服务器之间进行数百次调用,而每个进程中只使用了一两个线程。在客户端中,您没有任何被阻塞等待响应的内容 - 您只需准备好继续运行程序,等待响应即可。在服务器上,您没有任何被阻塞在 Thread.Sleep 调用上(逻辑同步等效于 Task.Delay) - 您只有很多继续运行程序的准备工作,在延迟到期时运行。
因此,是的,在双方都很好。无论在哪里使用它,您都可以获得好处。

非常感谢Jon。我知道使用async-await的响应优势。你的回答清楚地解释了可扩展性的优势。在客户端和服务器端都使用async将使用最少的资源。再次感谢您的回复。 - Learner
1
客户端代理上的新*Async方法是“本地异步”的。我在博客文章中写了关于WCF的async更新 - Stephen Cleary
@StephenCleary:感谢确认。这让很多事情都变得有意义。 - Jon Skeet
@Jon Skeet:请评论一下这个问题,因为我已经从您的答案中理解了一些内容。https://dev59.com/72nWa4cB1Zd3GeqPwg-Z#rIvjnYgBc1ULPQZFQhqr - Learner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接