Delegate.BeginVoke回调阻塞调用线程

本文关键字:调用 线程 BeginVoke 回调 Delegate | 更新日期: 2023-09-27 18:27:06

我真的不知道该从哪里处理这个问题,因为我对异步编程不是特别熟悉。我有一个循环,它调用委托的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调试器中)。

我认为我在进行委托异步调用的过程中犯了某种根本性错误,但我找不到任何文档来向我解释。知道为什么会发生这种情况吗?

更新

作为进一步测试的一部分,我在没有EndInvoke调用的情况下尝试了这个方法(我知道,这在实践中是个坏主意),但行为没有改变——它仍然无法继续执行循环。

Delegate.BeginVoke回调阻塞调用线程

我认为它对我来说还可以。你是在控制台应用程序中运行它吗?

你需要停止这种退出。

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