【问题标题】:How to get status of long running task如何获取长时间运行任务的状态
【发布时间】:2020-11-24 03:12:33
【问题描述】:

为什么我的TaskStatus 返回“WaitingForActivasion”而不是“Running”?
如果我删除 Task.Run 我会卡在 while 循环中,所以我假设它不是异步运行的。

public class StateManagerTest
{
    [Fact]
    public void Start_TaskStatus()
    {
        StateManager manager = new StateManager();
        manager.Start();

        Assert.True(manager.Status == System.Threading.Tasks.TaskStatus.Running.ToString());
    }
}

public class StateManager
{
    private CancellationTokenSource cts = new();
    private Task updateTask;
    public HashSet<StateItem> StateItems { get; private set; }
    public Provider Provider { get; private set; }
    public List<OutputService> OutputServices { get; private set; }

    public string Status
    {
        get => updateTask.Status.ToString();
    }

    public StateManager()
    {
        StateItems = new();
        OutputServices = new();
        Provider = new();
    }

    public void Stop()
    {
        cts.Cancel();
    }

    public void Start()
    {
        updateTask = Task.Run(() => Update(cts.Token))
            .ContinueWith(t => Debug.WriteLine(t.Exception.Message), TaskContinuationOptions.OnlyOnFaulted);
    }

    private async Task Update(CancellationToken token)
    {
        while (true)
        {
            // get changes from outputs
            Dictionary<StateItem, object> changes = new Dictionary<StateItem, object>();
            foreach (var service in OutputServices)
            {
                var outputChanges = await service.GetChanges();
                foreach (var change in outputChanges)
                    changes.TryAdd(change.Key, change.Value);
            }

            // write changes to provider source
            await Provider.PushChanges(changes);

            // update state
            await Provider.UpdateStateItems();

            // update all services
            foreach (var service in OutputServices)
                await service.UpdateSource();

            if (token.IsCancellationRequested)
                return;
        }
    }
}

【问题讨论】:

  • @TheGeneral 感谢您提供信息。但是 Update() 中的 while 循环是否仍在执行?还是我的 Start() 方法有问题?
  • “但是 Update() 中的 while 循环是否仍在执行” - 是的,直到它没有执行……但我认为更广泛的问题是你在这里真正想要实现什么?跨度>
  • 带有异步 lambda 的 Task.Run (或在您的情况下使用返回 Task 的 lambda )创建一个承诺式任务。 Promise 风格的任务永远不会转换到 Running 状态。您可以在这里查看更多详细信息:A Tour of Task, Part 3: Status
  • @TheodorZoulias 即使没有 Task.Run 它仍然是 WaitingForActivasion

标签: c# asynchronous async-await task


【解决方案1】:

正如其他人所指出的,WaitingForActivation is the correct state for a Promise Task that is not yet completed。一般来说,我建议不要使用Task.StatusContinueWith;它们是async/await存在之前的遗物。

如何获取长时间运行任务的状态

我相信您会想要progress reporting,这是您自己完成的。 T 中的 T 可以是 string,如果你想要一个简单的文本更新,或者一个 double,如果你想要一个百分比更新,或者自定义 struct,如果你想要一个更复杂的更新。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-13
    • 1970-01-01
    • 2014-05-04
    • 2016-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多