我正在嘗試調試多線程似乎失速的多線程應用程序,然後繼續工作幾分鐘或以後再也不再。線程在調試器中的標識線
我確定他們之間存在一個爭用點,這是造成這一點,但我不知道如何找到它。在Visual Studio中使用Parallel Stacks
和Threads
視圖僅向我提供線程啓動位置的堆棧,而不是它們當前的位置。
我開始我的任務有:
Task task = new Task((object state) => { DoWork(state).GetAwaiter().GetResult(); }, $"worker_task{i}", TaskCreationOptions.LongRunning);
然後,他們通過從ConcurrentQueue
拉項目,並處理它們的進程中運行。我使用GetAwaiter().GetResult();
,否則他們調用的異步方法會立即返回,即使仍在執行任務,任務也會顯示爲完成。
的Visual Studio調試窗口:
線程#38880實際上並沒有做任何工作,我想找出它被卡住,但它只能說明我在哪裏任務開始了。
如何查看當前任務/線程在哪一行?我是否以我看不見的方式開始我的任務?如果是這樣,我該怎麼做?
語境:我正在運行通過調用Httpclient
API的任務。由於網絡延遲,我正在並行運行多個任務,以便在等待時間內最大限度地提高CPU利用率。調用HttpClient是一個異步操作,我似乎無法創建一個任務,所以我最終創建了一個匿名函數並在其中進行了阻止。
這可能是錯誤的方法,但我不知道該怎麼辦。
方法啓動的任務:
private static void InitWorkers()
{
for(int i = 0; i < max_workers; i++)
{
Task task = new Task((object state) => { DoWork(state).GetAwaiter().GetResult(); }, $"worker_task{i}", TaskCreationOptions.LongRunning);
ProcessingTasks.TryAdd($"worker_task{i}", task);
processedStats.TryAdd($"worker_task{i}", new Stat());
task.Start();
}
}
如果您使用異步方法,爲什麼不使用'await'或'Task.ContinueWith()'來代替?我有一種感覺,'GetResult()'會阻擋你,但很難從那個截圖中確定。 – xxbbcc
@xxbbcc可能是因爲我是C#中的多線程新手。我想我正在犯很多天真的錯誤。這些任務長時間運行,並且正在對'HttpClient'進行異步調用,我正在並行處理多個任務。爲上下文添加mroe代碼 –
@DouglasGaskell:是;您應該瞭解更多關於'async'如何工作的信息。 Stephen Cleary有很多很好的博客文章。 https://msdn.microsoft.com/en-us/magazine/jj991977.aspx – SLaks