Редактировать, после расшифровки кода в вашем комментарии
Ваша проблема не с блокировкой или потоками, а с захватом переменной цикла. Это классическая проблема, все ваши потоки запускаются с «захватом» одной переменной V
, и к тому моменту, когда потоки будут выполнены, ее конечное значение достигнет 999. За исключением, может быть, первых нескольких рабочих элементов.
Итак, вместо:
foreach (double V in Values)
{
ThreadPool.QueueUserWorkItem(delegate(object state)
{ SaveValues(writer, V); }, V); // use of captured V: almost always 999
}
использование
foreach (double V in Values)
{
double W = V;
ThreadPool.QueueUserWorkItem(delegate(object state)
{ SaveValues(writer, W); }, V);
}
или, более кратко,
foreach (double V in Values)
{
double W = V;
ThreadPool.QueueUserWorkItem((state) => SaveValues(writer, W));
}
В качестве варианта ответа @ Matti рекомендуется заблокировать отдельный простой объект. Это снижает риск того, что что-то еще блокируется на том же объекте (например, сам код StreamWriter).
private StreamWriter writer = ...;
private Object writerLock = new Object(); // don't expose through a property
// or any other way
lock (writerLock)
{
writer.Write(...);
}
Но то, как вы настроили метод SaveValues(StreamWriter writer, ...)
, делает его немного сложнее. Лучше иметь объект, где writer
и writerLock
являются частными членами.