我在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中的广告。
答案 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);
}
}