【发布时间】:2020-04-16 13:54:02
【问题描述】:
** 我在底部总结了这个问题,并进行了编辑**
以前有人问过这个问题,但我认为我的情况不同。
我正在同时处理多个请求。
这是我的代码,它在循环中运行。为简洁起见,我删除了一些处理 taskAllocated 变量的代码。
while (!taskAllocated)
{
lock (_lock)
{
// Find an empty slot in the task queue to insert this task
for (i = 0; i < MaxNumTasks; i++)
{
if (_taskQueue[i] == null)
{
_taskQueue[i] = Task.Run(() => Process());
_taskQueue[i].ContinueWith(ProcessCompleted);
break;
}
}
}
}
Process是一个典型的async Task Process() { CpuIntensiveStuff(); }方法。
我一直在运行上面的代码,并且运行良好。它很好地多线程。每当有一个项目进来时,它就会在任务队列中找到一个空槽,然后将其启动。当任务完成时,ProcessCompleted 方法运行,并释放槽。
但后来我想,我不应该在我的Task.Run 中使用await 吗?比如:
_taskQueue[i] = Task.Run(async () => await Process());
想了想,我也不确定。 ContinueWith 在任务完成后正确触发,因此可能没有必要。
我问是因为我想监控和记录每项任务需要多长时间才能完成。
因此,我将创建另一种方法,而不是 Process():
async Task DoProcess()
{
var sw = Stopwatch.StartNew();
Process();
sw.Stop();
Log(sw.ElapsedMilliseconds);
}
我突然想到,如果我这样做了,我不确定是否需要await Process();,除了不知道我是否应该在Task.Run() 中等待
我对此有点紧张。谁能提供指导?
编辑:
总结一下:
如果某个方法是:
void SomeMethod() { }
然后
Task.Run(() => SomeMethod()); 很棒,在一个新的“线程”上调用 SomeMethod(技术上不是,但你知道我的意思)。
然而,我的SomeMethod其实是:
async Task SomeMethod() { }
您需要对Task.Run() 做一些特别的事情吗?
我的代码,我不是,我只是直接忽略了它是一个异步任务,而且这似乎有效:
Task.Run(() => SomeMethod()); // SomeMethod is async Task but I am ignoring that
但我不相信它 a) 应该有效或 b) 是一个好主意。替代方法可能是:
Task.Run(async() => await SomeMethod());
但是有什么意义吗?而这与我真正想做的事实相得益彰:
Task.Run(() =>
{
someCode();
var x = startTimer();
SomeMethod();
var y = stopTimer();
someMoreCode()
});
但如果没有等待,我不确定它是否会等待某个方法完成并且计时器会出错。
【问题讨论】:
-
不幸的是,并非如此。他们说
An async method returns to the caller as soon as the first await is hit,但这只是在等待的情况下,不是吗?如果你不等待它,它只会返回一个任务并继续运行。 -
@PavelAnikhouski 这个例子不太一样,因为它使用
await与.Result进行比较。 -
这个问题真的是和this重复的。匿名方法只是掩盖了这一点。这只是直接返回
Task或return await之间的区别。如果你用完整的方法(不是匿名方法)写出来,就会变得清晰。 -
您说
ProcessCompleted工作正常,这令人惊讶,因为您似乎创建了Task<Task>对象,这通常是一种糟糕的结束方式。如果我们有一个小的完整样本,我们可以自己运行和观察,这会有所帮助。 -
Task.Run可以also accept aFunc<Task>。从您的方法推断正在使用哪个重载。如果something()返回Task,则使用Func<Task>重载。但是,返回Task的方法存在特定重载这一事实让我想知道我的答案是否真的正确:) 我想测试一下......
标签: c# async-await task