当 Task.Status 更改为 运行 时,有没有办法收到通知?
Is there a way to be notified when Task.Status changes to running?
我正在编写一个 class 来运行任务并根据 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
}
}
你不能(有效地)。你可能做错了什么,and/or 如果你认为你需要这样做,就会做出一些无效的假设。
许多任务永远不会转换到 TaskStatus.Running
状态。例如,从 TaskCompletionSource<T>
创建的所有任务(包括异步方法返回的任务)直接从 WaitingForActivation
进入 3 个已完成状态之一。当它转换到 Running
时,没有任何任务会暴露给它的调用者(如果确实如此,它根本不会暴露)。
您可能 大致 知道它何时发生的唯一方法(除了轮询,这会很糟糕)是如果您确保所有任务都安排在您的自定义 TaskScheduler
从而知道你什么时候要执行它们。但正如我所说,您实际上是在逆流而上,应该重新考虑您认为依赖于此的任何设计。
我正在编写一个 class 来运行任务并根据 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
}
}
你不能(有效地)。你可能做错了什么,and/or 如果你认为你需要这样做,就会做出一些无效的假设。
许多任务永远不会转换到 TaskStatus.Running
状态。例如,从 TaskCompletionSource<T>
创建的所有任务(包括异步方法返回的任务)直接从 WaitingForActivation
进入 3 个已完成状态之一。当它转换到 Running
时,没有任何任务会暴露给它的调用者(如果确实如此,它根本不会暴露)。
您可能 大致 知道它何时发生的唯一方法(除了轮询,这会很糟糕)是如果您确保所有任务都安排在您的自定义 TaskScheduler
从而知道你什么时候要执行它们。但正如我所说,您实际上是在逆流而上,应该重新考虑您认为依赖于此的任何设计。