以下是我使用的代碼。主線程等待線程池線程執行。我使用AutoResetEvent(WaitHandle),但我真的很驚訝,因爲代碼不符合預期。使用AutoResetEvent同步.NET線程池
我有兩個同心for循環,其中Threadpool在內部循環中,並且期望對於外部循環的每次迭代,都應該處理所有內部循環值。主線程使用內部循環外部的AutoResetEvent WaitOne調用來等待,這是一個靜態變量,它在外循環的每次迭代時被重置爲內循環的最大值,並且在方法調用時使用Interlock遞減。調用AutoResetEvent的Set。但是,即使我希望靜態變量在每個內部循環後顯示0值,它也不會。我的代碼中存在什麼問題以及我有什麼更好的選擇來完成此任務?事實上,由於這些值的混合,主線程似乎並沒有等待線程池線程。
using System;
using System.Threading;
namespace TestThreads
{
class Program
{
private static int threadingCounter = 0;
private static readonly object lockThreads = new Object();
private AutoResetEvent areSync = new AutoResetEvent(true);
// <param name="args"></param>
static void Main(string[] args)
{
Program myProgram = new Program();
try
{
try
{
for (int outer = 0; outer < 1000; outer++)
{
threadingCounter = 500;
try
{
for (int inner = 0; inner < 500; inner++)
{
ThreadPool.QueueUserWorkItem(new
WaitCallback(myProgram.ThreadCall), inner);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
myProgram.areSync.WaitOne();
}
if(threadingCounter != 0)
Console.WriteLine("In Loop1, Thread Counter :: " +
threadingCounter);
}
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
}
catch(Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
threadingCounter = 0;
if (myProgram.areSync != null)
{
myProgram.areSync.Dispose();
myProgram.areSync = null;
}
}
}
public void ThreadCall(object state)
{
try
{
int inner = (int)state;
Thread.Sleep(1);
}
catch (Exception ex)
{
Console.WriteLine("Exception :: " + ex.Message);
}
finally
{
Interlocked.Decrement(ref threadingCounter);
if (threadingCounter <= 0)
areSync.Set();
}
}
}
}
你的異常處理是該死的糟糕。至少有一個可見的錯誤,您沒有正確使用Interlocked.Decrement。您必須使用它的返回值,並且*從不*在減量時直接使用該變量。使用CountDownEvent陷入成功之坑。 –
@HansPassant,你的評論是粗魯的,事實上不準確。 –
好吧,我被欺負,改寫。您的異常處理極大地增強了您的代碼的可讀性。訪問由其他線程修改的變量不是問題。更好? –