Mono-Async WCF异常--损坏或我的错误
本文关键字:我的 错误 损坏 WCF 异常 Mono-Async | 更新日期: 2023-09-27 18:26:38
我有一个WCF服务运行在CentOS 6.6+Mono 4.2.1上。如果契约方法是同步的,那么服务就可以工作,但如果可能的话,我希望使用异步(因为每个请求都有很多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(字符串url)和字符串GetUrl(字符串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中的错误还是我做错了什么?
我可以接受阻塞(在客户端上有一个超时,但希望服务器是异步的)。感谢您的帮助。
注意:A确实在Stack Overflow上看到了类似的声音问题,但听起来它在Mono 4.2中被添加了。
这样更改代码;
你的主要方法;
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);
}
}