我正在創建多個執行緒,將不同的資料傳遞給每個執行緒。但是,在 CallAsync 方法中,我有時會收到相同的資料。
為什么輸入和輸出資料不同?
如何正確地將唯一字串傳遞給每個執行緒?
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace NTest
{
class Program
{
static async Task<int> CallAsync(string str)
{
Console.WriteLine("income: {0}", str);
// await ...
return 0;
}
static async void WorkerMainAsync()
{
List<Task> trackedTasks = new List<Task>();
int[] jobs = new int[] { 0,1,2,3,4,5 };
string str;
foreach (int num in jobs)
{
str = num.ToString();
Console.WriteLine("pass: {0}", str);
trackedTasks.Add(Task.Run(() => CallAsync(str)));
}
await Task.WhenAll(trackedTasks);
Console.WriteLine("[*] All jobs finished.");
}
static void Main(string[] args)
{
WorkerMainAsync();
Console.ReadLine();
}
}
}
控制臺輸出:
pass: 0
pass: 1
pass: 2
income: 1
income: 2
pass: 3
pass: 4
income: 4
income: 4
income: 4
pass: 5
income: 5
[*] All jobs finished.
uj5u.com熱心網友回復:
這與方法是異步的這一事實沒有任何關系。
這種行為是因為 lambda 運算式關閉了變數,而不是值。所以運算式() => CallAsync(str)總是參考同一個str變數,最終在所有呼叫之間共享。
一個簡單的解決方法是在回圈內宣告變數,以便每個 lambda 閉包都有自己的變數:
int[] jobs = new int[] { 0,1,2,3,4,5 };
foreach (int num in jobs)
{
var str = num.ToString();
Console.WriteLine("pass: {0}", str);
trackedTasks.Add(Task.Run(() => CallAsync(str)));
}
await Task.WhenAll(trackedTasks);
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/359331.html
上一篇:最終List<T>和執行緒安全
