WCF 命名管道在 WinApp 中超时,但在 ConsoleApp 中没有?
Posted
技术标签:
【中文标题】WCF 命名管道在 WinApp 中超时,但在 ConsoleApp 中没有?【英文标题】:WCF Named Pipes timeout in a WinApp, but not in a ConsoleApp? 【发布时间】:2017-03-25 08:03:16 【问题描述】:关于Async two-way communication with Windows Named Pipes (.Net) 似乎已死(即线程):/
我想知道为什么下面的代码可以在 ConsoleApplications 中完美运行,但是当我对 WindowsApplications 执行完全相同的操作时,调用“Console.WriteLine(proxy.ProcessData());”时客户端会出现超时。奇怪的是,服务器方法“ProcessData”被调用,没有任何异常,但在默认1分钟后我仍然超时?!
我该如何解决这个问题...ConsoleApp 和 WinApp 之间到底有什么区别(除了显而易见的),这就是这样的东西不起作用的原因?
使用 WCF,您可以使用双工命名管道
// Create a contract that can be used as a callback
public interface IMyCallbackService
[OperationContract(IsOneWay = true)]
void NotifyClient();
// Define your service contract and specify the callback contract
[ServiceContract(CallbackContract = typeof(IMyCallbackService))]
public interface ISimpleService
[OperationContract]
string ProcessData();
实施服务
[ServiceBehavior(InstanceContextMode=InstanceContextMode.PerCall)]
public class SimpleService : ISimpleService
public string ProcessData()
// Get a handle to the call back channel
var callback = OperationContext.Current.GetCallbackChannel<IMyCallbackService>();
callback.NotifyClient();
return DateTime.Now.ToString();
托管服务
class Server
static void Main(string[] args)
// Create a service host with an named pipe endpoint
using (var host = new ServiceHost(typeof(SimpleService), new Uri("net.pipe://localhost")))
host.AddServiceEndpoint(typeof(ISimpleService), new NetNamedPipeBinding(), "SimpleService");
host.Open();
Console.WriteLine("Simple Service Running...");
Console.ReadLine();
host.Close();
创建客户端应用程序,在本例中,客户端类实现回调合约。
class Client : IMyCallbackService
static void Main(string[] args)
new Client().Run();
public void Run()
// Consume the service
var factory = new DuplexChannelFactory<ISimpleService>(new InstanceContext(this), new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/SimpleService"));
var proxy = factory.CreateChannel();
Console.WriteLine(proxy.ProcessData());
public void NotifyClient()
Console.WriteLine("Notification from Server");
【问题讨论】:
【参考方案1】:原因是同步上下文在调用回调时很重要。
你从ProcessData
内部调用回调方法。
如果控制台应用程序没有设置任何同步上下文,这意味着当ProcessData
返回时,当主线程正在等待时,WCF 将在单独的线程中调用客户端上的回调方法。如果您在控制台消息中记录线程 ID,您可以看到这一点。
如果是 Windows 应用程序主线程设置同步上下文(WinForms 或 WPF)。如果您从主线程调用您的服务,那么 WCF 将尝试在同一同步上下文中调用您的回调方法。但是这个同步上下文的唯一线程正忙于等待ProcessData
返回。
您可以通过两种方式解决这个问题:
1.设置UseSynchronizationContext=false
为您的回拨。
2. 从应用程序的后台线程调用您的服务 - 然后将在其他线程池线程上调用回调。
请注意,使用这两个选项,您无法直接从这些后台线程访问 UI 元素 - 您需要编组对 UI 线程的调用。
【讨论】:
以上是关于WCF 命名管道在 WinApp 中超时,但在 ConsoleApp 中没有?的主要内容,如果未能解决你的问题,请参考以下文章
当 2 个进程尝试同时在不同管道上相互通信时,使用命名管道的 WCF IPC 会崩溃