以下作品:
public static void Main( string[] args ){
Task FooTask = Task.Run( ( ) => Console.WriteLine( "Bar" )
).ContinueWith( T => Console.WriteLine( "Baz" ) );
FooTask.Wait( );
Console.WriteLine( "Press Enter To Exit." );
Console.ReadLine( );
}
以下不是 - (条形图打印,Baz不是)。
static void printFirstMessage( ){
console.WriteLine( "Bar" );
}
static void printFirstMessage( ){
Console.WriteLine( "Baz" );
}
public static void Main( string[] args ){
//I say "new Action( ... )" because if I don't, I get an IDE error
//that says "The call is ambiguous between..."
Task FooTask = Task.Run( new Action( printFirstMessage )
).ContinueWith( new Action( printSecondMessage ) );
Console.WriteLine( "Press Enter To Exit." );
Console.ReadLine( );
}
这是我真实问题的过度简化,我希望能够将两个方法链接到一个任务中,然后做一些其他的事情,然后在退出方法之前Wait( )
完成任务。
为什么第一个实例工作正常,但第二个实例失败?
答案 0 :(得分:3)
ContinueWith
不接受Action
作为第一个参数。事实上有很多不同的重载,但是它们都接受一个带有Task
的委托,以及可能的其他参数,ContinueWith
的不同重载除了委托之外还有其他参数。
如果您使用Action<Task>
而不是Action
(并提供了具有相应签名的方法),则代码将进行编译,如第一个示例所示。
答案 1 :(得分:1)
又一个愚蠢的任务。继续问题
你不应该使用ContinueWith
。 It's a low-level, inherently dangerous API with several non-obvious pitfalls
为什么第一个实例工作正常,但第二个实例失败?
正如Servy所回答的那样,因为ContinueWith
没有Action
参数 - 它需要Action<Task>
。但是,这确实是错误的问题......
这是对我真正问题的过度简化,我希望能够将两个方法链接到一个任务中,然后执行其他操作,然后在退出方法之前等待()执行任务。
正确的连锁方式是使用await
:
private static async Task DoBothAsync()
{
await Task.Run(() => Console.WriteLine("Bar"));
Console.WriteLine("Baz");
}
public static void Main(string[] args)
{
Task FooTask = DoBothAsync();
FooTask.Wait();
Console.WriteLine("Press Enter To Exit.");
Console.ReadLine();
}
另外,我发现使用Task.Run
有问题。可能没有必要。
答案 2 :(得分:0)
您在第二个示例中指定的语法不正确,甚至无法编译。如果你将语法更正为我认为你的意思(见下文),那么代码的工作原理与第一个例子相同:
static void printFirstMessage()
{
Console.WriteLine("Bar");
}
static void printSecondMessage()
{
Console.WriteLine("Baz");
}
public static void Main(string[] args)
{
Task FooTask = Task.Run(() => printFirstMessage())
.ContinueWith(t => printSecondMessage());
Console.WriteLine("Press Enter To Exit.");
Console.ReadLine();
}
答案 3 :(得分:0)
Task.Run()返回一个等待的任务,你在其上调用ContinueWith。 ContinueWith还返回一个等待的任务,这就是你需要从ContinueWith调用中返回一些内容的原因。试试这个,这将让你等待第二个任务(t)(printSecondMessage动作):
Task FooTask = Task.Run(() => printFirstMessage())
.ContinueWith(t => printSecondMessage());
FooTask.Wait();