簡體   English   中英

父任務不等待子任務完成

[英]Parent task does not wait for child task to complete

所以這是我的代碼

Task<int[]> parent = Task.Run(() =>
{
    var result = new int[3];

    TaskFactory tf = new TaskFactory(TaskCreationOptions.AttachedToParent, TaskContinuationOptions.ExecuteSynchronously);

    for (int i = 0; i < result.Length; i++)
    {
        int j = i;
        tf.StartNew(() => result[j] = GetRandomNumber(j));
    }

    return result;
});

var finalTask = parent.ContinueWith(parentTask =>
{
    foreach (var i in parentTask.Result)
    {
        Console.WriteLine(i);   
    }
});

finalTask.Wait();

基本上我創建3個Task ,這種是孩子Task稱為父(我猜)。 我要求父任務等待所有三個子任務完成。 之后,由於finalTask.Wait(); finalTask將等待執行finalTask.Wait(); 這個狀態。 但事情並沒有像預期的那樣發生。 我的意思是應用程序在任何GetRandomNumber調用完成之前退出。 這里的代碼的某些部分是從書中復制的,該書表明那些父任務應該等待子任務完成,這顯然沒有發生。 我在這里錯過了什么嗎?

這就是GetRandomNumber所做的

public static int GetRandomNumber(int ii)
{
    Random rand = new Random();

    for (int i = 0; i < 1000000000; i++) { } // imitate some jobs

    return rand.Next(1000);
}

這段代碼做了同樣的事情

Task<int[]> parent = Task.Run(() =>
{
    var result = new int[3];

    for (int i = 0; i < result.Length; i++)
    {
        int j = i;
        new Task(() => result[j] = GetRandomNumber(j), TaskCreationOptions.AttachedToParent).Start();
    }

    return result;
});

此行為是由於您使用Task.Run方法,該方法禁止將子任務附加到父級:

Run方法是StartNew方法的簡單替代方法。 它創建一個任務[其] CreationOptions屬性值為TaskCreationOptions.DenyChildAttach

要解決此問題,只需更改第一行即可

Task<int[]> parent = Task.Run(() =>

Task<int[]> parent = Task.Factory.StartNew(() =>

Task.Run的文檔中,您會發現它指定了

其CreationOptions屬性值為TaskCreationOptions.DenyChildAttach。

因此,即使您指定了TaskCreationOptions.AttachedToParentTaskCreationOptions.AttachedToParent其忽略。

請使用以下代碼:

static void RunParentTask()
    {
        Task<int[]> parent = Task.Factory.StartNew<int[]>(() =>
        {
            var results = new int[3];

            TaskFactory<int> factory = new TaskFactory<int>(TaskCreationOptions.AttachedToParent,
                                                            TaskContinuationOptions.ExecuteSynchronously);
            factory.StartNew(() => results[0] = 1);
            factory.StartNew(() => results[1] = 2);
            factory.StartNew(() => results[2] = 3);

            return results;
        });

        parent.Wait();

        foreach (var item in parent.Result)
        {
            Console.WriteLine(item);
        }
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM