1

我有一个类,其中每个方法都异步执行,即返回一个任务,但是每个方法都应该等待前面的调用完成。

继续,对吧?

除了任务延续在参数中采用委托(Action),而不是另一个任务。

我尝试了不同的东西,我能做的最好的事情是下面的(对我来说非常复杂)代码:

    private Task QueueTask(Func<Task> futureTask)
    {
        var completionSource = new TaskCompletionSource<int>();

        _lastTask.ContinueWith(async t =>
        {
            try
            {
                await futureTask();

                completionSource.SetResult(0);
            }
            catch (Exception ex)
            {
                completionSource.SetException(ex);
            }
        });

        _lastTask = completionSource.Task;

        return _lastTask;
    }

这里 _lastTask 是我班级的私人成员。由于所有调用都来自 UI 线程,我只保留最后一个任务并继续执行它。

正如我所说,我发现这段代码非常复杂。你有更好的建议吗?

4

1 回答 1

2

在我看来,你好像问错了问题。像这样的任务队列是一个不寻常的要求。我们对您要解决的实际问题一无所知,因此我们无法提出更好的方法。

ContinueWith用于动态并行处理,因此不太适合async代码。但是,您可以使用ContinueWithpaired withUnwrap来模拟await(如果您忽略await与当前上下文的交互方式)的行为。

因此,您可以像这样简化任务队列解决方案:

private Task QueueTask(Func<Task> futureTask)
{
    _lastTask = _lastTask.ContinueWith(t => futureTask()).Unwrap();
    return _lastTask;
}

但是,可能有更好的解决方案。如果队列的目的是提供独占访问,aSemaphoreSlim会更自然。如果您出于某种原因确实需要队列,请考虑使用 Dataflow 网格。

于 2013-07-09T16:58:06.467 回答