在创建新Control后创建时,WCF服务冻结

时间:2013-12-23 12:17:45

标签: c# winforms wcf

我有以下示例项目:

namespace ConsoleApplication1
{
    [ServiceContract]
    public interface IFoo
    {
        [OperationContract]
        string GetText();
    }

    public class Foo : IFoo
    {
        public string GetText()
        {
            return "foo";
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            using (var host = new ServiceHost(typeof(Foo), new Uri("http://localhost:9995/foo")))
            {
                host.AddServiceEndpoint(typeof(IFoo), new BasicHttpBinding(), "");

                //new Control();
                host.Open();
                Console.ReadKey();
            }
        }
    }
}

哪种方法正常,当我取消注释行new Control()并再次运行应用程序时,服务将停止工作。

有人知道为什么会这样吗?为什么在调用host.Open()之前创建新的Control会阻止WCF服务工作?

注意:在调试了一些服务不起作用的大项目后,我发现了这个问题。似乎只有在创建了一些UserControl之后才创建出现问题的服务。

1 个答案:

答案 0 :(得分:1)

如果在启动UI线程之前打开了ServiceHost实例,它将在自己的线程上运行。否则它将使用消息循环(UI线程)。

在您的情况下,在打开主机之前创建新的Control时,wcf将使用消息循环。同时这个:Console.ReadKey()阻止主线程,所以你的应用程序挂起。

如果你这样写:

//Console.ReadKey();
while (true)
{
    Application.DoEvents();
    Thread.Sleep(100);
}

它会起作用。试试吧。

有关详细信息,请参阅here和一些SO答案: WCF threading - non-responsive UI

还有一本很棒的书link完全(我认为是这样)你的问题。

修改

调用host.Open()时,WCF正在检查SynchronizationContext.Current的值(请参阅SynchronisationContext)。如果它是null,则WCF将使用新上下文,如果它不为null,则WCF将使用现有上下文。

new Control() SynchronizationContext.Current被称为null之后,SynchronizationContext.Current = WindowsFormsSynchronizationContext Console.ReadKey()被称为host.AddServiceEndpoint(typeof(IFoo), new BasicHttpBinding(), ""); // this will force WindowsFormsSynchronizationContext to be created new Control(); // create new sync context, and WCF will use it, not WinForms context SynchronizationContext.SetSynchronizationContext(new SynchronizationContext()); host.Open(); // WCF will respond Console.ReadKey(); // main thread is blocked 。这意味着使用主线程和消息循环,但{{1}}阻止主线程。所以app挂了。

另一种解决方案是这样写:

{{1}}