我使用ThreadPool执行同步操作。每个操作都成功执行。我还通过Monitor.Enter方法锁定了这些操作,因为如果我不这样做,我就会遇到线程冲突问题。问题是在运行我的应用程序后,我发现操作的执行顺序错误。这是我的代码:
using System.Threading;
private static readonly Object obj = new Object();
public void Test()
{
List<int> list1 = new List<int>();
for (int i = 0; i < 10; i++) list1.Add(i);
int toProcess = list1.Count;
using (ManualResetEvent resetEvent = new ManualResetEvent(false))
{
for (int i = 0; i < list1.Count; i++)
{
var idx = i;
ThreadPool.QueueUserWorkItem(
new WaitCallback(delegate(object state)
{
WriteToConsole(list1[idx]);
if (Interlocked.Decrement(ref toProcess) == 0)
resetEvent.Set();
}), null);
}
resetEvent.WaitOne();
}
}
private void WriteToConsole(int p)
{
bool lockWasTaken = false;
var temp = obj;
Monitor.Enter(temp, ref lockWasTaken);
Console.Write(p.ToString());
Monitor.Exit(temp);
}
0 1 2 3 7 五 9 6 4 8
我该怎么做才能解决错误的订单?
由于
答案 0 :(得分:1)
我该怎么做才能解决错误的订单?
无。应该是这样的。当您并行处理项目时,通常无法保证执行顺序。所以你的选择是:
答案 1 :(得分:1)
如果您订购了它,它本身意味着您按顺序处理它。如果希望按顺序完成,则根本不需要线程。
那就是说,你不必再直接处理线程池了。使用Task.Run
或Task.Factory.StartNew
。然后,您可以使用Task.WaitAll
或Task.WhenAll
等待其完成。
此外,您的WriteToConsole
方法也是多余的。 Console.Write
访问不需要被锁定,因为它已经是线程安全的。它可以简单地写成
private void WriteToConsole(int p)
{
Console.Write(p);
}