簡體   English   中英

為什么這么慢,.net任務嵌套子任務

[英]why is so slow, .net task nest sub task

我創建了一個asp.net webapi測試應用程序,這是我的測試代碼:

當我使用result = index.ToString() + this.getresult().Result; ,響應時間是2s。 如果我使用Thread.Sleep(100); result = index.ToString(); Thread.Sleep(100); result = index.ToString(); ,它只需要200ms。

public class HomeController : Controller
{
    public string Test()
    {
        var listName = new List<int>();

        for (int i = 0; i < 100; i++)
        {
            listName.Add(i);
        }

        var response = Task.WhenAll(listName.Select(sendrequest)).Result;

        return string.Join(",", response);
    }

    public async Task<string> sendrequest(int index)
    {
        return await Task.Factory.StartNew(() =>
        {
            string result = string.Empty;

            try
            {
                Thread.Sleep(100); result = index.ToString();
                //result = index.ToString() + this.getresult().Result;
            }
            catch (Exception ex)
            {
                System.IO.File.AppendAllText("D:\\WebService\\FelixTest\\log.txt",ex.ToString());
            }

            return result;

        }).ConfigureAwait(false);
    }

    public async Task<string> getresult()
    {
        await Task.Delay(100);

        return "OK";
    }
}

我認為你正在遭受ThreadPool線程飢餓。 問題出在你已注釋掉的那一行

//result = index.ToString() + this.getresult().Result;

通過訪問Task.Result屬性,您將導致從getresult()方法返回的TaskWait Wait操作阻止當前線程執行,這意味着必須在另一個線程上安排下一個Task,依此類推。 當您啟動所有將阻止的100個任務時,ThreadPool將嘗試啟動新的托管線程以滿足需求,這是一個耗時的過程。

我會重新組織你的代碼,以便一切都是異步的,除了一個頂級的Test方法。 在這個例子中,我不確定為什么你需要Task.Factory.StartNew()因為任務已經(至少部分地)並行運行,因為它們使用async-await模式。 也許您的真實示例需要在后台線程上安排任務? 如果您不需要使用Factory.StartNew()我建議重寫sendrequest如下所示: -

public async Task<string> sendrequest(int index)
{
    string result = string.Empty;
    try
    {
        result = index.ToString() + await this.getresult();
    }
    catch (Exception ex)
    {
        System.IO.File.AppendAllText("D:\\WebService\\FelixTest\\log.txt",ex.ToString());
    }

    return result;
}

如果確實需要使用Factory.StartNew()您仍然可以實現相同的功能,但是傳遞給StartNew的委托應該標記為async

根據您的描述,差異是1800毫秒。 getresult你有100毫秒的延遲。 如果我們減去它,差值是1700毫秒。 帶有"OK"字符串連接並不能解釋這一點。 因此,您可能會使用循環,並且getresult的延遲為100毫秒getresult增加一個重要的等待時間。

暫無
暫無

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

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