【问题标题】:How to use Visual Studio - generated async WCF calls?如何使用 Visual Studio - 生成异步 WCF 调用?
【发布时间】:2012-12-08 13:04:17
【问题描述】:

我的OperationContract

public List<MessageDTO> GetMessages()
        {
            List<MessageDTO> messages = new List<MessageDTO>();
            foreach (Message m in _context.Messages.ToList())
            {
                messages.Add(new MessageDTO()
                {
                    MessageID = m.MessageID,
                    Content = m.Content,
                    Date = m.Date,
                    HasAttachments = m.HasAttachments,
                    MailingListID = (int)m.MailingListID,
                    SenderID = (int)m.SenderID,
                    Subject = m.Subject
                });
            }
            return messages;
        }

在服务参考配置中,我选中了“生成异步操作”选项。如何使用生成的GetMessagesAsync()?在网上我找到了使用AsyncCallback 的示例,但是我对此并不熟悉。有没有办法以某种友好的方式使用它,例如 .NET 4.5 中的 asyncawait 关键字?如果不是,我应该怎么做才能异步调用该方法?

【问题讨论】:

    标签: c# .net wcf asynchronous


    【解决方案1】:

    如果您选择“生成异步操作”,您将获得必须使用回调的“旧”行为。

    如果您想使用新的 async/await 语法,则必须选择“生成基于任务的操作”(默认选中)。

    当使用默认的 Wcf 模板时,这将生成以下代理代码:

      public System.Threading.Tasks.Task<string> GetDataAsync(int value) {
          return base.Channel.GetDataAsync(value);
      }
    

    如您所见,不再有回调。而是返回 Task&lt;T&gt;

    您可以通过以下方式使用此代理:

    public static async Task Foo()
    {
        using (ServiceReference1.Service1Client client = new ServiceReference1.Service1Client())
        {
            Task<string> t = client.GetDataAsync(1);
            string result = await t;
        }
    }
    

    你应该用async标记调用方法,然后在调用你的服务方法时使用await

    【讨论】:

    • 如果您使用 .NET V4.5 及更高版本,则启用“生成基于任务的操作”选项。
    • @ManasKumar 你能把它作为一个单独的问题发布吗?这将允许人们回答它。
    【解决方案2】:

    您的服务参考(如果您使用的是 .Net 4.5)可以设置为生成基于任务的异步调用。 (配置服务参考>检查允许生成异步操作>选择生成基于任务的操作)这些可以像任何async方法一样使用。这是一个如何使用它的示例:

    using (var proxy = new YourServiceClient())
    {
        var t1 = proxy.GetMessagesAsync();
        var t2 = proxy.GetMessagesAsync();
        //they're runnning asynchronously now!
    
        //let's wait for the results:
        Task.WaitAll(t1, t2);
        var result1 = t1.Result;
        var result2 = t2.Result;
        Console.WriteLine(result1);
        Console.WriteLine(result2);
    }
    

    如果您的客户端未使用 .Net 4.5,则无法生成使用 async 的服务引用。你必须用老式的方法,使用回调。这是一个例子:

    static void m()
    {
        var proxy = new YourServiceClient();
        proxy.GetMessagesCompleted += proxy_GetMessagesCompleted;
        proxy.GetMessagesAsync();
    }
    
    static void proxy_GetMessagesCompleted(object sender, GetMessagesCompletedEventArgs e)
    {
        var proxy = (IDisposable)sender;
        proxy.Dispose(); //actual code to close properly is more complex
    
        if (e.Error != null)
        {
            // do something about this
        }
    
        var result = e.Result;
        Console.WriteLine(result);
    }
    

    请注意,在这些场景的实际代码中,您不应该使用usingIDisposable.Dispose() 来清理客户端,请参阅Avoiding Problems with the Using Statementthis code 让您开始进入令人困惑的关闭世界这些东西。

    【讨论】:

      【解决方案3】:

      如果您使用的是 VS2012,那么您可以像这样使用 *Async 调用:

      var proxy = new MyClient();
      var result = await proxy.GetMessagesAsync();
      

      【讨论】:

        【解决方案4】:

        这样的事情怎么样...

        public async Task<string> DoSomething()
        {
        var someProxy = new ServiceClient();
        
        var t = someProxy.SomeMethodAsync();
        await Task.WhenAny(t);
        
        return t.Result;
        

        }

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-10-29
          • 1970-01-01
          • 2012-10-03
          相关资源
          最近更新 更多