2012-03-08 105 views
1

我真的不知道在哪裏看這個問題,因爲我不是特別熟悉異步編程。我有一個調用委託的BeginInvoke方法的循環。當代理的回調執行時,循環停止執行(不應該)。我猜測它運行的線程被阻塞,但我確實不知道。下面的代碼的簡化版本:Delegate.BeginInvoke回調阻塞調用線程?

public class TestClass 
{ 
    private readonly IService service; 
    private delegate void TestDelegate(); 
    private bool conditionIsMet = true; 

    public TestClass(IService service) 
    { 
     this.service = service; 
    } 

    public void PerformTask() 
    { 
     while (conditionIsMet) 
     { 
      var testDelegate = new TestDelegate(service.DoSomething); 
      testDelegate.BeginInvoke(TestCallback, null); 

      Thread.Sleep(1); 
     } 
    } 

    private void TestCallback(IAsyncResult result) 
    { 
     var asyncResult = (AsyncResult) result; 
     var testDelegate = (TestDelegate) asyncResult.AsyncDelegate; 
     testDelegate.EndInvoke(asyncResult); 

     // After exiting this method the loop in PerformTask() ceases to execute. 
     // Is it being blocked here somehow? 
    } 
} 

在實踐中,更多的是位代碼,但涉及的基本組成部分都在這裏只要我可以告訴。在上面的代碼示例中,我在其中放置了一條註釋,以指示代碼執行的最後一個位置(無論如何,都在VS調試器中)。

我認爲我在做某種在我做委託異步調用方式的根本錯誤的,但我找不到解釋給我的任何文檔。任何想法爲什麼發生這種情況?

UPDATE

中進一步測試的一部分,我想這沒有EndInvoke會調用(我知道,在實踐中壞主意),但在行爲上沒有改變 - 它仍然未能繼續執行循環。

+0

你可以聲明'conditionIsMet'爲'volatile',並且檢查誰在改變這個標誌。 – oleksii 2012-03-08 16:24:37

+0

我想這不會傷害嘗試這個,但我不認爲這將有助於在這種情況下。循環的條件只能通過父線程設置(當服務停止時)。我會試一試,看看會發生什麼。乾杯, – 2012-03-08 16:57:35

+0

不,不幸的是,這種方法沒有改變。 – 2012-03-08 16:59:14

回答

0

它的作品確定爲我,我認爲。你是否在控制檯應用程序中運行它?

您將需要停止流出。

class Program 
{ 
    static void Main(string[] args) 
    { 
     TestClass t = new TestClass(new Service()); 
     t.PerformTask(); 

     Console.ReadKey(); 
    } 
} 

public class Service : IService 
{ 
    public void DoSomething() 
    { 
     Console.WriteLine("Doing something"); 
    } 
} 

public class TestClass 
{ 
    private readonly IService service; 
    private delegate void TestDelegate(); 
    private bool conditionIsMet = true; 

    public TestClass(IService service) 
    { 
     this.service = service; 
    } 

    public void PerformTask() 
    { 
     while (conditionIsMet) 
     { 
      var testDelegate = new TestDelegate(service.DoSomething); 
      testDelegate.BeginInvoke(TestCallback, null); 

      Thread.Sleep(1); 
     } 
    } 

    private void TestCallback(IAsyncResult result) 
    { 
     var asyncResult = (AsyncResult)result; 
     var testDelegate = (TestDelegate)asyncResult.AsyncDelegate; 
     testDelegate.EndInvoke(asyncResult); 

     // After exiting this method the loop in PerformTask() ceases to execute. 
     // Is it being blocked here somehow? 
    } 
} 

public interface IService 
{ 
    void DoSomething(); 
} 
+0

它的運行作爲Windows服務的一部分 - while循環不會退出,除非該服務被停止。基本上循環是從隊列中讀取的,並且每當在隊列中找到一個項目時,它應該異步處理該項目 - 但是循環不應該由於任何原因而退出。我通過在循環後放置一個斷點來驗證這一點,但它從未被擊中。 – 2012-03-08 16:52:05