单声道异步WCF异常 - 破碎或我的错误?

时间:2015-12-12 00:00:12

标签: c# wcf mono async-await

我在CentOS 6.6 + Mono 4.2.1上运行WCF服务。如果契约方法是同步的,那么该服务是有效的,但是如果可能的话我想使用异步(因为每个请求都有很多I / O密集型任务)。但是当我尝试将任何服务实现为异步时,我在Mono下运行时会遇到异常。我已经为repro包含了一个虚拟测试方法:

服务器

[OperationContract]
Task<string> GetUrl(string url);

async public Task<string> GetUrl(string url)
{
    MailUtils.LogText(LogLevel.Verbose, () => String.Format("Got request for {0}", url));
    string result = String.Empty;

    try
    {
        using (var client = new WebClient())
            result = await client.DownloadStringTaskAsync(url);
    }
    finally
    {
        MailUtils.LogText(LogLevel.Verbose, () => String.Format("Leaving GetUrl(); Got {0} byte(s)", result.Length));
    }
    return result;
}

客户端(命令行实用程序):

static void Main(string[] args)
{
    if (args.Length == 2 && args[0] == "-testasync")
    {
        try
        {
            MailSorterServiceClient client = new MailSorterServiceClient();
            var task = client.GetUrlAsync(args[1]);

            task.Wait();

            Console.WriteLine(String.Format("Success: Got {0} byte(s)", (task.Result ?? "").Length));
        }
        catch(Exception ex)
        {
            Console.WriteLine(ex.InnerException.Message);
            Console.WriteLine(ex.InnerException.StackTrace);
        }
        return;
    }

据我所知,服务器没有收到请求,客户端获得异​​常:

Object reference not set to an instance of an object
  at System.ServiceModel.Dispatcher.BaseMessagesFormatter.DeserializeReply (System.ServiceModel.Channels.Message message, System.Object[] parameters) [0x000ea] in /root/src/mono-4.2.1/mcs/class/System.ServiceModel/System.ServiceModel.Dispatcher/BaseMessagesFormatter.cs:289

其他

Visual Studio生成的客户端有两种方法:

任务GetUrlAsync(string url) 和字符串GetUrl(string url)

如果我更改我的客户端代码以调用GetUrl(),请求将通过服务器进程并显示服务器日志:

[12/11/2015 3:06 PM]: Got request for http://www.google.com/
[12/11/2015 3:06 PM]: Leaving GetUrl(); Got 188337 byte(s)

...但是客户端在从服务器收到响应之前返回(客户端返回一个空字符串并且没有错误的指示)。

异步代码在Windows下按预期工作。

这是Mono中的错误还是我做错了什么?

我可以阻止(在客户端上使用timeout_但希望服务器是异步的)。任何帮助表示赞赏。

注意:A确实看到了类似的声音问题on Stack Overflow,但听起来好像是在Mono 4.2中的广告。

1 个答案:

答案 0 :(得分:0)

像这样更改你的代码;

您的主要方法;

  if (args.Length == 2 && args[0] == "-testasync")
  {
       CallWebService(args[1]);
  }

然后是您的网络服务电话;

   private static async void CallWebService(string url)
   {
          try
          {
              using (MailSorterServiceClient client = new MailSorterServiceClient())
               {
                   var result = await client.GetUrlAsync(url);

                   Console.WriteLine(result.ToString());
               }
           }
           catch (Exception ex)
           {
               Console.WriteLine(ex.InnerException.Message);
               Console.WriteLine(ex.InnerException.StackTrace);
           }
     }