C#Tasks.ContinueWith

0 c# asynchronous task continuewith

我试图从异步方法执行两个不同的任务,但我的第二个任务应该从第一个任务开始.我试过使用ContinueWith但没有成功.这是我的示例代码:

class Program
{
    static List<string> GlobalList1 = null;
    static List<string> GlobalList2 = null;

    static void Main(string[] args)
    {
        Task firstTask = new Task(DoFirstThing);
        firstTask.Start();
        firstTask.Wait();

        Task secondTask = firstTask.ContinueWith(o => DoSecondThing(), TaskContinuationOptions.ExecuteSynchronously);
        secondTask.Wait();

        Console.ReadKey();
    }

    public async static void DoFirstThing()
    {
        Console.WriteLine("Doing first...");

        Task t = new Task(FirstThing);
        t.Start();

        await t;
    }

    public async static void DoSecondThing()
    {
        Console.WriteLine("Doing second...");

        Task t = new Task(SecondThing);
        t.Start();


        await t;
    }

    private async static void FirstThing()
    {
        Console.WriteLine("In First..");

        Task t = new Task(() =>
        {
            List<string> list = new List<string>();

            for (int i = 0; i < 1000; i++)
            {
                list.Add(string.Format("Testing:{0}", i));
            }

            System.Threading.Thread.Sleep(2000);

            GlobalList1 = list;
        });

        t.Start();

        await t;
    }

    private async static void SecondThing()
    {
        Console.WriteLine("In Second...");

        Task t = new Task(() =>
        {
            GlobalList2 = new List<string>();
            for (int i = 0; i < GlobalList1.Count; i++)
            {
                GlobalList2.Add(GlobalList1[i].ToString() + " - testing");
            }
        });

        t.Start();
        await t;
    }
}
Run Code Online (Sandbox Code Playgroud)

您可能会通过控制台输出注意到任务同时保持运行.是否有可能改变这种行为?

Jon*_*eet 5

我的第二个任务应该从第一个任务开始

然后你应该真的等待它完成.目前,你没有这样做.你正在等待DoFirstThing返回的方法,但它会等待之前完成t.

如果不是构建一个新的Task然后调用Start(),而是调用Task.Run并提供一个Func<T>,则可以等待代理任务完成:

static void Main(string[] args)
{
    Task firstTask = Task.Run(DoFirstThing);
    firstTask.Wait();
    ...
}

public async static Task DoFirstThing()
{
    Console.WriteLine("Doing first...");

    Task t = Task.Run(FirstThing);

    await t;
}

private async static Task FirstThing() { ... }
Run Code Online (Sandbox Code Playgroud)

现在,Wait()FirstThing()异步操作真正完成之前,调用将无法完成.

基本上,async void几乎在所有情况下都避免使用方法.

那说:

  • 显式启动任务而不仅仅是调用异步方法通常不是一个好主意.
  • 显式调用Wait()而不是等待任务也很少是一个好主意,因为如果给定任务具有必须在同一线程上运行的延续,它可能会死锁.