在WinApp中,WCF命名管道超时,而在ConsoleApp中,WCF命名管道超时吗? [英] WCF Named Pipes timeout in a WinApp, but not in a ConsoleApp?

查看:106
本文介绍了在WinApp中,WCF命名管道超时,而在ConsoleApp中,WCF命名管道超时吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于与Windows命名的异步双向通信管道(.Net)似乎已失效(即线程):/

In relation to Async two-way communication with Windows Named Pipes (.Net) which seems dead (the thread that is) :/

我想知道为什么以下代码在ConsoleApplications中可以完美地工作,但是当我对WindowsApplications执行完全相同的操作时,在调用"Console.WriteLine(proxy.ProcessData());"时,客户端会超时.奇怪的是,服务器方法"ProcessData"的调用没有任何异常,但是在默认的1分钟后仍然会超时吗?!

I'm wondering why the following code works perfectly in a ConsoleApplications, but when I do exactly the same thing with WindowsApplications I get an timeout on the client when calling "Console.WriteLine(proxy.ProcessData());". The strange thing is that the server method "ProcessData" is called without any exceptions, but still I get a timeout after the default 1 min?!

如何解决此问题...以及ConsoleApp和WinApp之间的区别到底是什么(除了显而易见的原因),这就是为什么这种方法行不通的原因?

How can I fix this... and what exactly is the difference between between and ConsoleApp and a WinApp (besides the obvious) which is the reason something like this doesn't work?

使用WCF,您可以使用双工命名管道

Using WCF you can use duplex named pipes

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

创建客户端应用程序,在此示例中,Client类实现了回调合同.

Create the client application, in this example the Client class implements the call back contract.

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

推荐答案

原因是同步上下文对于调用回调很重要. 您可以从ProcessData内部调用回调方法.

The reason is synchronization context that is important when callback is called. You call callback method from inside ProcessData.

对于控制台应用程序,没有任何同步上下文设置,这意味着WCF将在ProcessData返回时在主线程等待时在单独线程中的客户端上调用回调方法.如果您在控制台消息中记录线程ID,则可以看到此信息.

In case of console application there is no any synchronization context set, which means that WCF will call callback method on the client in the separate thread while main thread is waiting when ProcessData returns. You can see this if you log thread ID in your console messages.

对于Windows应用程序,主线程设置同步上下文(WinForms或WPF).如果从主线程调用服务,则WCF将尝试在相同的同步上下文中调用回调方法.但是,此同步上下文的唯一线程正忙于等待ProcessData返回.

In case of Windows application main thread sets synchronization context (either WinForms or WPF). If you call your service from main thread, then WCF will try to call your callback method in the same synchronization context. But the only thread of this synchronization context is busy with waiting for ProcessData to return.

您可以通过两种方法解决此问题: 1.为您的回调设置UseSynchronizationContext=false. 2.从应用程序的后台线程调用您的服务-然后将在其他线程池线程上调用回调.

You can solve that by two means: 1. Set UseSynchronizationContext=false for your callback. 2. Call your service from background thread of the application - then callback will be called on some other threadpool thread.

请注意,使用这两个选项,您将无法直接从这些后台线程访问UI元素-您需要封送对UI线程的调用.

Be aware that with both options you can't access UI elements from these background threads directly - you'll need to marshal calls to UI thread.

这篇关于在WinApp中,WCF命名管道超时,而在ConsoleApp中,WCF命名管道超时吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆