Я последовательно запускаю три операции через пул потоков. У них одинаковый приоритет. Однако порядок их исполнения не всегда тот, в котором я их запускал. Почему это происходит?
Я ожидал, что пул потоков запустит мои задачи в том же порядке, в котором они будут отправлены мной в очередь запросов пула потоков (если они имеют одинаковый приоритет).
using System;
using System.Runtime.Remoting.Messaging;
using System.Threading;
namespace ThreadsLearning {
class Foo {
public string Name { get; set; }
public override string ToString() {
return Name;
}
}
class Program {
private static void Main(string[] args) {
Console.WriteLine("Main method works...");
Foo foo = new Foo { Name = "Bob" };
CallContext.LogicalSetData("name", foo);
ThreadPool.QueueUserWorkItem(state => Console.WriteLine("1: Name = {0}",
CallContext.LogicalGetData("name")));
ExecutionContext.SuppressFlow();
ThreadPool.QueueUserWorkItem(state => Console.WriteLine("2: Name = {0}",
CallContext.LogicalGetData("name")));
ExecutionContext.RestoreFlow();
ThreadPool.QueueUserWorkItem(state => Console.WriteLine("3: Name = {0}",
CallContext.LogicalGetData("name")));
Console.WriteLine("Hit <Enter> for exit...");
Console.ReadLine();
}
}
}
Выход может быть:
Main method works...
Hit <Enter> for exit...
2: Name =
1: Name = Bob
3: Name = Bob
или
Main method works...
1: Name = Bob
2: Name =
3: Name = Bob
Hit <Enter> for exit...
UPD
Я попытался сделать то же самое с потоком и получить ту же проблему:
using System;
using System.IO;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
namespace ThreadsLearning {
class Foo {
public string Name { get; set; }
public override string ToString() {
return Name;
}
}
class Program {
private static void Main(string[] args) {
using (MemoryStream ms = new MemoryStream()) {
using (StreamWriter sw = new StreamWriter(ms, Encoding.UTF8, 0x1000, true)) {
sw.WriteLine("Main method works...");
Foo foo = new Foo { Name = "Bob" };
CallContext.LogicalSetData("name", foo);
ThreadPool.QueueUserWorkItem(state => sw.WriteLine("1: Name = {0}",
CallContext.LogicalGetData("name")));
ExecutionContext.SuppressFlow();
ThreadPool.QueueUserWorkItem(state => sw.WriteLine("2: Name = {0}",
CallContext.LogicalGetData("name")));
ExecutionContext.RestoreFlow();
ThreadPool.QueueUserWorkItem(state => sw.WriteLine("3: Name = {0}",
CallContext.LogicalGetData("name")));
Thread.Sleep(2000); // Postpone the ws.Dispose() call.
}
using (StreamReader sr = new StreamReader(ms, Encoding.UTF8)) {
Console.WriteLine("Stream length: {0} bytes", ms.Length);
ms.Position = 0;
Console.WriteLine("Data: \n{0}", sr.ReadToEnd());
}
}
Console.WriteLine("Hit <Enter> for exit...");
Console.ReadLine();
}
}
}