有没有办法在Task.Status更改为运行时收到通知?

Joh*_*son 2 c# events inotifypropertychanged async-await

我正在编写一个运行任务的类,并基于通知.

有一个问题我想不出解决的是如何当Task.Status从去通知TaskStatus.WaitingForActivationTaskStatus.Running.

缩短的代码如下:

using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;

public abstract class ExecutionTracker : INotifyPropertyChanged
{
    protected ExecutionTracker(Task task)
    {
        Task = task;
        AwaitTask(task);
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public Task Task { get; }

    public TaskStatus Status => Task.Status;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }

    private async void AwaitTask(Task task)
    {
        try
        {
            // This is where status goes from WaitingForActivation to Running
            // and I want to do OnPropertyChanged(nameof(Status)) when it happens.
            // A hack would be setting a flag awaiting = true here and return TaskStatus.Running if the flag is true.
            // ^ feels nasty
            await task.ConfigureAwait(false);
        }
            // ReSharper disable once EmptyGeneralCatchClause We don't want to propagate errors here. Just make them bindable.
        catch
        {
        }

        // Signal propertychanges depending on result
    }
}
Run Code Online (Sandbox Code Playgroud)

And*_*ott 6

你不能(有效).如果您认为自己需要这样做,那么您可能做错了什么,并且/或者做出了一些无效的假设.

许多任务永远不会过渡到TaskStatus.Running州.例如,从a创建的所有任务TaskCompletionSource<T>(包括由异步方法返回的任务)直接从WaitingForActivation3个已完成状态之一.并且任何任务在转换到它时都不会向其调用者公开Running(如果确实如此,它确实会这样做).

你可能大致知道它发生的唯一方法(除了轮询,这将是非常糟糕的)将是你确保所有任务都安排在你的自定义上TaskScheduler,从而知道你什么时候执行它们.但正如我所说,你真的在​​这里游泳,应该重新考虑你认为取决于此的任何设计.