1

We have a WCF logger wrapped in a windows service which exposes various methods which I can successfully call both synchronously and asynchronously from a simple console test app. Running the service from studio in debug mode I can see the various breakpoints being hit and we get the expected output.

When I call the same service methods synchronously from another WCF service the methods all work fine also...

using (var logger = new LoggerServiceClient())
    logger.Log(...);

However, if I change to the Async method of invocation it simply does nothing...

using (var logger = new LoggerServiceClient())
    logger.LogAsync(...);

I get no errors raised, the code happily continues on but nothing hits the logger service. It can't be permissions because the synchronous method calls work.

Like I say, the same code and config is in the test console app and that works perfectly. I can simply add or remove the "Async" suffix in the calling service though and the behaviour is different. We're using w7, framework 4.0, using tpl and 4.5 is not currently an option.

This has me stumped so any ideas, however strange, will be considered.

Mike
  • 2,120
  • 1
  • 23
  • 40
  • Did you try to await the Async call? `await logger.LogAsync(...)`, omitting the await keyword can cause unexpected behavior. – Rafal Mar 19 '15 at 06:09
  • Like I mentioned, this is using 4.0 - as I understand it Async/Await have only been introduced with C# 5.0 and .NET Framework 4.5 – Mike Mar 19 '15 at 06:15
  • Yes and no, the await keyword is a compiler feature and it [can be used on framework 4](http://stackoverflow.com/questions/9110472/using-async-await-on-net-4) using vs2012 or even vs2010. Regardless of that if your application is not async ready you should not us async calls. – Rafal Mar 19 '15 at 06:25

1 Answers1

0

logger.LogAsync() method will return immediately. As you use logger with using statement, logger object will also be disposed immediately. It may be cause of nothing hits the logger service.

Try to remove using statement:

var logger = new LoggerServiceClient();
logger.LogAsync(...);

UPDATED

I just found an article Do not use “using” in WCF Client. There is example for closing WCF client in syncronous mode.

For asyncronous client call you can close WCF client in Task's continuation:

logger.LogAsync(...).ContinueWith(x => {
    // check task
    if (x.IsFaulted)
    {
        // you need to touch x.Exception property here
        // or your application will crash because of unhandled exception
        Console.WriteLine("LogAsync error occured: {0}", x.Exception);
    }
    try
    {
        logger.Close();
    }
    catch (CommunicationException e)
    {
        logger.Abort();
    }
    catch (TimeoutException e)
    {
        logger.Abort();
    }
    catch (Exception e)
    {
        // you will want to log this exception to log file
        Console.WriteLine("LogAsync client close error: {0}", e);
        logger.Abort();
        // no throw here or your application will crash
    }
});

The continuation lambda body is long and you may want to reuse it. So, it is worth to write an extension method for continuations.

Hope this helps.

hal
  • 1,705
  • 1
  • 22
  • 28
  • The using theory makes sense, I'll give that a go over the weekend (the code's move on a bit so I'll have to recreate). I'll let you know how I get on. Cheers – Mike Mar 20 '15 at 07:20