我正在编写一个运行任务并基于this进行通知的类。

我想不出解决方案的一个问题是,如何在Task.Status从TaskStatus.WaitingForActivation变为TaskStatus.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
    }
}

最佳答案

您不能(有效)。如果您认为自己需要这样做,可能是在做错事,并且/或者做出了一些无效的假设。

许多任务从不转换为TaskStatus.Running状态。例如,从TaskCompletionSource<T>创建的所有任务(包括异步方法返回的任务)直接从WaitingForActivation进入3个已完成状态之一。过渡到Running时,任何Task都不会向其调用者公开(如果确实如此,那么它确实会这样做)。

您大概知道大概什么时候发生的唯一方法(除了轮询之外,这是很糟糕的)是,如果您确保所有任务都在自定义TaskScheduler上安排了,从而知道了何时执行它们。但是,正如我所说,您确实是在上游游泳,应该重新考虑您认为与此相关的任何设计。

关于c# - Task.Status更改为正在运行时,是否有一种通知方式?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34811639/

10-15 07:20