【问题标题】:Inter-process communication with named pipe and WCF Service: threading issue与命名管道和 WCF 服务的进程间通信:线程问题
【发布时间】:2012-02-17 21:55:14
【问题描述】:

我有两个进程:一个是 GUI,另一个是 CUI。 它们每个都托管一个简单的 WCF 服务,并通过名称管道相互通信。

GUI 应用程序中有两个按钮和一个进度条。

“开始运行”按钮告诉 CUI 运行任务 30 秒。 CUI 将其进度报告回 GUI,因此可以更新进度条。 “打印”按钮告诉 CUI 打印一个字符串。

现在如果我们按下“打印”按钮几次,没关系,CUI 将打印字符串:

然后,如果我按下“开始运行”按钮,CUI 会将进度打印到控制台并将进度报告回 GUI,并且进度条会更新:

然后我可以再按几次“打印”按钮,它就可以了:

这一切看起来都很好。

但是如果我重新启动这两个进程,然后先单击“开始运行”按钮,然后单击“打印”按钮,那么两个进程都会被冻结:

看起来像是线程问题。

所以看起来如果我从单击打印按钮开始,那么一切正常。 但是如果我从点击开始运行按钮开始,那么就会出现死锁。 这是为什么呢?

您可以从这里下载此示例:http://files.cnblogs.com/cuipengfei/SampleForStackOverflow.zip

【问题讨论】:

    标签: .net multithreading wcf ipc named-pipes


    【解决方案1】:

    当您调用 worker.Print() 时会出现死锁,因为它不会为 worker 创建新对象,而是尝试重用同一个对象。如果您将该调用放在另一个线程中,那么您会看到该调用在 worker.RunTask(30) 完成后执行。

    首先,我考虑将 InstanceContextMode.Single 更改为 InstanceContextMode.PerCall,因此它每次调用都会创建一个对象,而不是为所有调用使用同一个对象。这并没有解决问题。

    重新测试您提供的案例研究,如果您让完成 worker.RunTask(30),它也可以工作。所以我认为问题出现了,如果你在调用第二个电话之前从未完成过一个电话。然后它尝试重用相同的服务器实例。一旦你完全打完一个电话,它就会按预期工作。

    但是,解决您的问题的方法是打开到您的服务器的多个连接:

    NetNamedPipeBinding binding2 = new NetNamedPipeBinding();
    worker2 = ChannelFactory<IWorker>.CreateChannel(binding2, endpointAddress);
    

    然后使用它来访问打印操作:

    worker2.Print();
    

    【讨论】:

    • 顺便说一句,我们也可以通过在另一个线程中运行任务来解决这个问题。
    猜你喜欢
    • 2011-05-07
    • 2021-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多