Wpis z mikrobloga

List threadList = new List();
ResponseStreamList[] streamsByCategory = new ResponseStreamList[links.Length];
for (int i = links.Length - 1; i >= 0; i--)
{
//streamsByCategory[i] = GetStreamsFromLink(links[i]);
threadList.Add(new Thread(delegate() {streamsByCategory[i] = GetStreamsFromLink(links[i]); }));
threadList.Last().Start();
}

dlaczego jak odpale kod z komentarza to wszystko jest ok, a jak zamiast niego użyję tych wątków to i jakimś magicznym sposobem przyjmuje wartość -1 i wyrzuca IndexOutOfBounds?

#csharp #naukaprogramowania #dotnet
  • 6
@jaggi: https://blogs.msdn.microsoft.com/ericlippert/2009/11/12/closing-over-the-loop-variable-considered-harmful/

Innymi słowy - Twoje domknięcie przyjmuje i a nie wartość i. Co powoduje, że jak pętla się skończy to i = -1 i z taką wartością wykonuje się któryś z delegatów, tym samym indeksując tablicę [i], czyli [-1].

Powinno zadziałać jak zrobisz:

for (int i = links.Length - 1; i >= 0; i--)
{
var i2 = i;
//streamsByCategory[i] = GetStreamsFromLink(links[i]);
threadList.Add(new Thread(delegate() {streamsByCategory[i2] = GetStreamsFromLink(links[i2]); }));
threadList.Last().Start();
}
@jaggi: PS Ćwiczysz wątki czy coś? Bo generalnie ten kod jest bardzo brzydki i trudny w zarządzaniu. C# obecnie udostępnia Ci dużo fajniejsze sposoby na zarządzanie asynchronicznością/wielowątkowością. Wątki to bardzo nisko poziomowe obiekty i zwykle chcesz je tworzyć tylko i wyłącznie wtedy, kiedy potrzebujesz bardzo dużej "władzy" nad tym co się dzieje.