Run
是的,因为不应该有。
为了这个答案
Task
或
Task<T>
表示执行某些操作并返回一个值
可能存在,也可能不存在
. 它是对各种工作的抽象(例如,在另一个线程上运行的并发操作、在硬件中的其他地方运行的异步IO操作、同步操作的表示或其他东西)。
多棒的
任务
/
做
不
Func<>
或
Action<>
.
Task.Run
具体来说:真实的
Task.Run(Func<>)
/
Task.Run(Action)
启动
一
功能<>
或
行动<>
在默认调度程序的线程池中(即并发、多线程)。你不能“重启”a
任务
(一)
任务
的状态机图是严格单向的),只能启动新的
任务
. 因此不能任意重新启动异步
Socket
如果你有
任务<T>
对象,则(假设您正确使用了它)它表示的任何操作都将已计划或以其他方式启动-或已完成-因此您不能“启动”一个
任务
把它传给
因为它已经启动了(这是一个过于简单化的过程)。
你给出的例子(转载如下)没有任何用处:
public static Task Run(Task task) => Task.Run(async () => await task);
我把它改写成下面的长格式,以便更容易理解:
public static Task Run(Task originalTask)
{
LambdaCapture capture = new LambdaCapture( originalTask );
Task poolTask = Run( capture.Run ); // Remember that a Delegate includes the `this` reference unlike a raw C-style function-pointer.
return poolTask;
}
// Oversimplified representation of what Task.Run does:
public static Task Run( Action action )
{
ThreadPool pool = GetThreadPoolFromSomewhere();
TaskCompletionSource tsc = new TaskCompletionSource();
Action wrappedAction = () =>
{
// Run the action:
action();
// When it completes, inform TaskCompletionSource:
tsc.SetResult(); // Task (not `Task<T>`) has no result value.
// When `SetResult()` is invoked, the thread running this code will not return to here until after it runs the contination scheduled after `originalTask`.
};
pool.AddJob( wrappedAction ); // Adds `wrappedAction` to a queue which is dequeued by the first available thread.
return tsc.Task; // <-- this is a new Task created by the TaskCompletionSource.
}
private class LambdaCapture
{
private readonly Task originalTask;
public Runnable( Task originalTask )
{
this.originalTask = originalTask;
}
public async Task Run()
{
await this.originalTask;
}
}
Task.Run(Task)
方法被调用,它执行以下操作:
-
会安排的
LambdaCapture.Run
-
然后它将创建并返回一个单独的新
任务
实例来表示线程池操作(即并发操作),而不考虑
originalTask
.
-
,它会
检查是否
原阿尔塔斯克
已完成,如果是,将返回并通知
原阿尔塔斯克
Runnable.Run
(即
await
-只是一个
return;
原阿尔塔斯克
延续
-
所以当
完成(假设
原阿尔塔斯克
然后运行其余的
操作并通知工作线程池调度程序已完成,然后(可能)执行
等待
awaits
这个
从返回
任务。运行
.
-
如果这让人困惑,那是因为我不善于解释。
任务<T>
在C#中的工作方式与
Promise<T>
std::promise
简而言之:除了在线程池线程中浪费CPU周期之外,没有理由按照您的建议去做。正如@Fabio所说,只要做
await task
等待任务
在你原来的方法中,因为那个方法不是
async
方法,即使
仍然
需要
等待
这个
任务
是由
任务。运行