2012-03-08 70 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