[英]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()
方法返回的Task
上Wait
。 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.