使用 ManualResetEvent 进行并行编程
Parallel programming with ManualResetEvent
我有一种方法可以处理 List<string>
并行。不幸的是我不能使用 .NET 4+。
但是当我运行这个方法时,i
总是items.Count
public static void ParallelForEachTest(List<string> items)
{
if (items != null && items.Count > 0)
{
List<ManualResetEvent> mEventList = new List<ManualResetEvent>();
for (int i = 0; i < items.Count ; i++)
{
ManualResetEvent mEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem((y) =>
{
Console.WriteLine(items[i] + i);
mEvent.Set();
});
mEventList.Add(mEvent);
}
mEventList.ForEach(x => x.WaitOne());
}
}
我需要更改什么才能实现
x 0
x 1
x 2
对于ParallelForEachTest(new List<string>(){"x","x","x"});
在Console.WriteLine
执行的时候,循环已经结束,循环变量i
有最终值,等于list.Count
.
为了让每个任务打印其对应的索引,您必须将索引值传递给任务本身:
ThreadPool.QueueUserWorkItem((y) => { ... }, i);
第二个参数是任务启动后将传递给回调的状态。
此外,请确保不要使用闭包从任务内部访问状态。仅使用任务状态传输数据:
public static void ParallelForEachTest(List<string> items)
{
if (items != null && items.Count > 0)
{
List<ManualResetEvent> mEventList = new List<ManualResetEvent>();
for (int i = 0; i < items.Count; i++)
{
ManualResetEvent mEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(
(state) =>
{
Tuple<string, int, ManualResetEvent> tuple =
(Tuple<string, int, ManualResetEvent>)state;
Console.WriteLine(tuple.Item1 + tuple.Item2);
tuple.Item3.Set();
},
Tuple.Create(items[i], i, mEvent));
mEventList.Add(mEvent);
}
mEventList.ForEach(x => x.WaitOne());
}
}
我有一种方法可以处理 List<string>
并行。不幸的是我不能使用 .NET 4+。
但是当我运行这个方法时,i
总是items.Count
public static void ParallelForEachTest(List<string> items)
{
if (items != null && items.Count > 0)
{
List<ManualResetEvent> mEventList = new List<ManualResetEvent>();
for (int i = 0; i < items.Count ; i++)
{
ManualResetEvent mEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem((y) =>
{
Console.WriteLine(items[i] + i);
mEvent.Set();
});
mEventList.Add(mEvent);
}
mEventList.ForEach(x => x.WaitOne());
}
}
我需要更改什么才能实现
x 0
x 1
x 2
对于ParallelForEachTest(new List<string>(){"x","x","x"});
在Console.WriteLine
执行的时候,循环已经结束,循环变量i
有最终值,等于list.Count
.
为了让每个任务打印其对应的索引,您必须将索引值传递给任务本身:
ThreadPool.QueueUserWorkItem((y) => { ... }, i);
第二个参数是任务启动后将传递给回调的状态。
此外,请确保不要使用闭包从任务内部访问状态。仅使用任务状态传输数据:
public static void ParallelForEachTest(List<string> items)
{
if (items != null && items.Count > 0)
{
List<ManualResetEvent> mEventList = new List<ManualResetEvent>();
for (int i = 0; i < items.Count; i++)
{
ManualResetEvent mEvent = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(
(state) =>
{
Tuple<string, int, ManualResetEvent> tuple =
(Tuple<string, int, ManualResetEvent>)state;
Console.WriteLine(tuple.Item1 + tuple.Item2);
tuple.Item3.Set();
},
Tuple.Create(items[i], i, mEvent));
mEventList.Add(mEvent);
}
mEventList.ForEach(x => x.WaitOne());
}
}