2013-12-23 81 views
0

凍結我有一個下面的示例項目: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()之前創建一個新的控件,阻止WCF服務工作?

注:我發現了這個問題,調試一個大的項目,其中的一些服務不工作後。就顯得有些UserControl創建後與有問題的服務只創建。

回答

1

如果您在啓動UI線程之前打開ServiceHost實例,它將在其自己的線程上運行。否則,它將使用消息循環(UI線程)。

在你的情況,當創建一個新的控制打開主機之前,WCF將使用消息循環。同時這個:Console.ReadKey()阻止主線程,所以你的應用程序掛起。

如果你會寫這樣的:

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

它將工作。嘗試一下。

欲瞭解更多詳細信息來源看here而一些答案: WCF threading - non-responsive UI

還有一本偉大的書link與準確(我是這麼認爲的)你的問題。

編輯

host.Open()被稱爲WCF是檢查的SynchronizationContext.Current值(見SynchronisationContext)。如果是null則WCF將使用新的背景下,如果不爲空WCF將使用現有的上下文。

在您致電new Control()之前SynchronizationContext.Currentnull之後,它被稱爲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 
+0

感謝您的回答!它適用於我在問題中粘貼的示例項目以及我正在調試的目標項目。 –

+0

不客氣!我提醒了另一個解決方案,也許你會更喜歡它。 – Tony