C# 等待似乎不是等待

C# 等待似乎不是等待,c#,C#,我创建了一个用于重用线程的类。此类有一个用于将作业排队的公共方法 public AwaitableJob<T> PrepareJob(Func<T> job) { lock (locker) { var aj = new AwaitableJob<T>(job); taskQueue.Enqueue(aj); System.Threading.Mon

我创建了一个用于重用线程的类。此类有一个用于将作业排队的公共方法

public AwaitableJob<T> PrepareJob(Func<T> job)
    {
        lock (locker)
        {
            var aj = new AwaitableJob<T>(job);
            taskQueue.Enqueue(aj);
            System.Threading.Monitor.PulseAll(locker);
            return aj;
        }
    }
但它不是等待,而是继续执行,所以atm变量总是空的。当我在AwatiableJob中添加断点时,它显示在IsCompleted设置为true之前调用了GetResult。有人知道哪里会出问题吗?谢谢您的帮助。

问题出在这里:

public void OnCompleted(Action continuation)
{
    continuation.Invoke();
}
OnCompleted
的要点是注册一个回调,当它完成时,但是您现在正在调用continuation。您唯一应该这样做的时间是针对线程竞争条件,其中有人检查
IsCompleted
并获得
false
,但状态在这和注册回调之间发生更改。除此之外,您应该做的是存储回调,并从实际改变状态的代码中调用它(看起来像您的代码>调用/<代码>方法),再次记住在切换时考虑线程安全性。
坦率地说,如果这听起来很复杂:使用
TaskCompletionSource

重用线程可能会有问题。有些设置是特定于线程的,因此它们会在作业中保持不变(我想到了文化)。您确定需要实现自己的线程池吗?与现有线程池方法不同的是,我强烈建议不要创建自己的等待对象。在极少数情况下这是合适的,而这不是其中之一。您应该在任何时候使用
Task
来获得可等待的对象。这可能是使用
async void
的问题
async void
实际上只适用于事件处理程序,而不是您需要确保等待整个任务的任何东西。使用
async Task
作为返回类型,不返回任何内容,但仍然能够返回wait@JamesFaix不,这不是
async void
方法的结果,而是所示代码中等待对象的不正确实现的结果。我不理解您的
INotifyCompletion
实现。您的
OnCompleted()
方法应该只注册一个完成回调,它会立即调用该回调。因此,框架自然认为您的等待已经完成,而不是等待。不可能确切地知道发生了什么,因为您没有费心提供一个,当然,您可能不应该实现自己的等待。但是如果你真的想要一个答案,你需要改进这个问题。谢谢你的纠正和解释。现在它等待着。
public async void Connect()
    {
        var atm = await Worker.PrepareJob(ConnectHelper) as PresentModel; 

        if (atm == null) return;
        var vm = new SwitchingViewModel(atm);
        vm.NavigateTo();
    }
public void OnCompleted(Action continuation)
{
    continuation.Invoke();
}