gpt4 book ai didi

c# - 创建一个任务列表,包含任务但不执行

转载 作者:太空狗 更新时间:2023-10-30 00:25:02 25 4
gpt4 key购买 nike

我有一个异步方法

private async Task DoSomething(CancellationToken token)

任务列表

private List<Task> workers = new List<Task>();

我必须创建 N 个运行该方法的线程

public void CreateThreads(int n)
{
tokenSource = new CancellationTokenSource();
token = tokenSource.Token;
for (int i = 0; i < n; i++)
{
workers.Add(DoSomething(token));
}
}

但问题是那些必须在给定时间运行

public async Task StartAllWorkers()
{
if (workers.Count > 0)
{
try
{
while (workers.Count > 0)
{
Task finishedWorker = await Task.WhenAny(workers.ToArray());
workers.Remove(finishedWorker);
finishedWorker.Dispose();
}
if (workers.Count == 0)
{
tokenSource = null;
}
}
catch (OperationCanceledException)
{
throw;
}
}
}

但实际上它们在我调用 CreateThreads 方法时运行(在 StartAllWorkers 之前)。我搜索了关键字和类似我的问题,但找不到有关停止任务运行的任何信息。我尝试了很多不同的方法,但任何可以完全解决我的问题的方法。例如,将代码从 DoSomething 移动到 workers.Add(new Task(async () => { }, token)); 将运行 StartAllWorkers (),但线程永远不会真正启动。

还有另一种调用tokenSource.Cancel()的方法。

最佳答案

您可以使用 TaskCompletionSource<T>作为异步方法的一次性“信号”。

所以你会像这样创建它:

private TaskCompletionSource<object> _tcs;
public void CreateThreads(int n)
{
_tcs = new TaskCompletionSource<object>();
tokenSource = new CancellationTokenSource();
token = tokenSource.Token;
for (int i = 0; i < n; i++)
{
workers.Add(DoSomething(_tcs.Task, token));
}
}

然后当你准备开始任务时,只需完成“开始”信号任务:

public Task StartAllWorkers()
{
_tcs.TrySetCompleted(null);
return Task.WhenAll(workers);
}

(上面的 StartAllWorkers 方法与您的原始方法略有不同语义:您的原始方法会在第一个任务取消后立即抛出取消异常;这个方法将等到所有方法完成然后抛出取消异常)

然后是你的DoSomething只需要遵守“开始信号”:

private static async Task DoSomething(Task start, CancellationToken token)
{
await start;
... // rest of your code
}

关于c# - 创建一个任务列表,包含任务但不执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19616714/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com