又一个愚蠢的任务。继续与问题

时间:2017-01-20 20:04:53

标签: c# async-await task

以下作品:

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( )完成任务。

为什么第一个实例工作正常,但第二个实例失败?

4 个答案:

答案 0 :(得分:3)

ContinueWith不接受Action作为第一个参数。事实上有很多不同的重载,但是它们都接受一个带有Task的委托,以及可能的其他参数,ContinueWith的不同重载除了委托之外还有其他参数。

如果您使用Action<Task>而不是Action(并提供了具有相应签名的方法),则代码将进行编译,如第一个示例所示。

答案 1 :(得分:1)

  

又一个愚蠢的任务。继续问题

你不应该使用ContinueWithIt'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();