3

我已经创建了一个 WCF 服务,并且它的操作合同和实现如下所示:

    [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();

它显示了我的实现的 2 种方法: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,它有什么优势吗?

请指导。

4

1 回答 1

8

我不知道为 WCF 生成的代码是什么样的,但我希望第二种形式会更好。(编辑:阅读斯蒂芬的博客文章,了解为什么这是真的。)

第一种方法创建一个同步调用该方法的新任务——只要方法返回就阻塞一个线程。因此,如果您同时有很多这样的调用,您最终将使用大量线程并因此使用内存。

我希望第二种方法更加“本机”异步 - 基本上发送请求,然后在返回时在可能不同的线程上处理响应。

对于你的最后一个问题:

对于第二个调用,我在两个地方(客户端服务器)使用 async-await,它有什么优势吗?

您在两个片段await中的两个地方都使用了。但是,是的,在这两个地方都使用异步代码肯定是有优势的。在客户端中,您正在保存客户端线程。在服务器中,您正在保存服务器线程。

使用纯异步版本,您可以有数百次从客户端到服务器的调用,而在每个进程中不使用超过一两个线程。在客户端中,您没有任何阻塞,等待响应 - 您只需准备好在响应通过时调用延续。在服务器中,您没有在Thread.Sleep调用中阻塞任何内容(逻辑同步等效于Task.Delay) - 当延迟到期时,您只需准备好运行很多延续。

所以,是的,每一方面都很好。基本上,无论您在哪里使用它,您都可以获得好处。

于 2012-09-28T06:23:49.070 回答