我尝试创建将运行异步方法的任务,问题是我无法await
任务构造函数中的Action
参数,或者参数Task.Factory.StartNew
。
根据我实例化任务的方式,我有不同的问题。我已经提供了七个例子,其中包含对每个问题的评论。
示例代码:(创建任务的七个示例)
private ConcurrentDictionary<int, Task> Tasks { get; set; }
private bool active = true;
private async Task StartTasks()
{
int numTasks = 5;
for(int i = 0; i < numTasks; i++)
{
//Task status is almost instantly "RanTocompletion" while work is still being done
Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Cannot await method group
Task task = new Task(await DoWork, "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Task status is almost instantly "RanTocompletion" while work is still being done
Task task = new Task(async (object state) => await DoWork(state), "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Throws a "Start may not be called on a promise-style task." Exception
Task task = new Task<Task>(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap();
task.Start();
//Task starts doing work after Start() is called, then throws a "Start may not be called on a promise-style task." Exception
Task task = new Task(DoWork, "someinfo", TaskCreationOptions.LongRunning);
task.Start();
//Task starts doing work, but status is "WaitingForActivation
Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning);
//Throws a "Start may not be called on a promise-style task." Exception
Task task = Task.Factory.StartNew(DoWork, "someinfo", TaskCreationOptions.LongRunning).Unwrap();
//For checking up on tasks as work is done
Tasks.TryAdd(task.Id, Task);
}
}
private async Task DoWork(object state)
{
while (active)
{
await MakeHttpRequest();
await DoSomethingCpuBound();
//..etc
}
//do any cleanup and return
}
我无法使用Task.Run()
,因为它不提供TaskCreationOptions
。这些任务将在字面上运行。
如何启动任务以等待异步操作?
答案 0 :(得分:2)
如何启动任务以等待异步操作?
在TAP中,tasks are returned "hot"。所以你只需要调用方法并保持它返回的任务:
private ConcurrentDictionary<int, Task> Tasks { get; set; }
private async Task StartTasks()
{
for(int i = 0; i < 5; i++)
{
Task task = DoWork(null);
Tasks.TryAdd(task.Id, task);
}
}
我无法使用Task.Run(),因为它不提供TaskCreationOptions。这些任务将在字面上运行。
您不需要TaskCreationOptions
。 The LongRunning
flag is just a hint, and the thread pool will recover within a couple of seconds even if you don't specify that hint。但这并不重要,因为你的工作是异步所以它不需要首先在线程池上运行。