无法从其他 WCF 服务异步调用 WCF 服务上的方法,但可以同步

Cannot call method on WCF service from other WCF service ASync but can Sync

我们有一个包装在 windows 服务中的 WCF 记录器,它公开了我可以从一个简单的控制台测试应用程序同步和异步成功调用的各种方法。 运行 在调试模式下来自工作室的服务我可以看到各种断点被击中,我们得到了预期的输出。

当我从另一个 WCF 服务 同步 调用相同的服务方法时,所有方法都可以正常工作...

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

但是,如果我更改为 Async 调用方法,它什么都不做...

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

我没有收到任何错误,代码愉快地继续,但没有命中记录器服务。它不能是权限,因为同步方法调用有效。

就像我说的,相同的代码和配置在测试控制台应用程序中并且运行良好。我可以简单地在调用服务中添加或删除 "Async" 后缀,但行为是不同的。我们正在使用 w7,框架 4.0,使用 tpl 和 4.5 目前不是一个选项。

这让我很困惑,所以任何想法,无论多么奇怪,都会被考虑。

logger.LogAsync() 方法将立即 return。 当您使用 using 语句使用 logger 时,logger 对象也将立即被释放。这可能是没有命中记录器服务的原因。

尝试删除 using 语句:

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

已更新

我刚找到一篇文章 Do not use “using” in WCF Client。有在同步模式下关闭 WCF 客户端的示例。

对于异步客户端调用,您可以在任务的延续中关闭 WCF 客户端:

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
    }
});

continuation lambda 主体很长,您可能想要重用它。所以,为continuations写一个扩展方法是值得的。

希望对您有所帮助。