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

C# 无法从其他WCF服务异步调用WCF服务上的方法,但可以同步,c#,web-services,wcf,asynchronous,.net-4.0,C#,Web Services,Wcf,Asynchronous,.net 4.0,我们有一个包装在windows服务中的WCF记录器,它公开了各种方法,我可以通过一个简单的控制台测试应用程序成功地同步和异步调用这些方法。在调试模式下从studio运行服务时,我可以看到各种断点被击中,我们得到了预期的输出 当我从另一个WCF服务同步调用相同的服务方法时,这些方法也可以正常工作 using (var logger = new LoggerServiceClient()) logger.Log(...); 但是,如果我改为异步调用方法,它将什么也不做 using (var

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

当我从另一个WCF服务同步调用相同的服务方法时,这些方法也可以正常工作

using (var logger = new LoggerServiceClient())
    logger.Log(...);
但是,如果我改为异步调用方法,它将什么也不做

using (var logger = new LoggerServiceClient())
    logger.LogAsync(...);
我没有收到任何错误,代码很高兴地继续运行,但没有任何东西击中记录器服务。它不能是权限,因为同步方法调用work

就像我所说的,测试控制台应用程序中有相同的代码和配置,并且工作得非常好。不过,我可以简单地在调用服务中添加或删除异步后缀,其行为是不同的。我们正在使用w7,框架4.0,使用tpl和4.5目前不是一个选项


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

logger.LogAsync方法将立即返回。 当您使用带有using语句的logger时,logger对象也将立即被释放。这可能是日志记录程序服务未命中的原因

尝试使用以下语句删除:

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

我刚找到一篇文章。有一个以同步模式关闭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
    }
});
延续lambda主体很长,您可能希望重用它。因此,值得为continuations编写一个扩展方法


希望这有帮助。

您是否尝试等待异步调用?await logger.LogAsync…,省略await关键字可能会导致意外行为。如我所述,这是使用4.0-据我所知,Async/await仅在C 5.0和.NET Framework 4.5中引入是和否,await关键字是一种编译器功能,它使用vs2012甚至vs2010。不管怎样,如果你的应用程序还没有准备好异步,你就不应该使用异步调用。使用理论是有道理的,我会在周末让代码移动一点,所以我必须重新创建。我会告诉你我的进展。干杯