I have a WCF service running on CentOS 6.6 + Mono 4.2.1. The service works if contract methods are synchronous, but I would like to make use of async if possible (since there is a lot of I/O intensive tasks that go into each request). When I try and implement any of the service as async, though, I get an exception when I run under Mono. I've included a dummy test method for repro:
Server:
[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;
}
Client (command line utility):
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;
}
So far as I can tell the server does not receive the request and the client gets an exception:
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
Additional:
The client generated by Visual Studio has two methods:
Task GetUrlAsync(string url) and string GetUrl(string url)
If I change my client code to call GetUrl() the request makes it through to the server process and the server log shows:
[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)
... but the client returns before it receives the response from the server (client gets back an empty string and no indication of an error).
The async code works as expected under Windows.
Is this a bug in Mono or am I doing something wrong?
I am okay with blocking (with a timeout_ on the client but want the server to be async). Any help is appreciated.
Note: A did see a similar sounding problem on Stack Overflow but it sounds like it was addessed in Mono 4.2.