目前,我在一个只能从一个线程访问的项目中拥有多个资源。一个例子是ZeroMQ服务器,另一个例子是三菱PLC通信模块,这不是线程安全。
现在,我为任何需要单线程访问的资源创建一个单独的线程。我没有将它封装在类或任何东西中,所以我在每个类中都有一个ThreadStart (void)方法和几个属性,需要对资源进行协调访问。然后,我使用与Invoke / BeginInvoke相结合的dispatcher强制从单独线程进行访问。
是否已有一些类可以协调从单个线程对资源的访问?
下面是一些示例代码,现在可以为我找到一个分配器:
object theLock = new object();
Dispatcher dispatcher = null;
lock (theLock)
{
new Thread(new ThreadStart(() =>
{
lock (theLock)
{
dispatcher = Dispatcher.CurrentDispatcher;
Monitor.Pulse(theLock);
}
Dispatcher.Run();
})).Start();
Monitor.Wait(theLock);
}
dispatcher.Invoke(...);我可以将这些代码包装在类中,以便在需要时创建线程和调度程序,但我无法想象这是协调对线程不安全资源的访问的最佳解决方案。
发布于 2012-02-29 14:30:09
你试过使用任务和BlockingCollection吗?您可以在需要访问资源的任务中排队,并启动一个任务来排队列并运行该任务,然后一个接一个地运行,这样就没有竞争条件了?
static BlockingCollection<Action<StringBuilder>> queue = new BlockingCollection<Action<StringBuilder>>();
//Your thread unsafe resource...
static StringBuilder resource = new StringBuilder();
static void Main(string[] args)
{
Task.Factory.StartNew(() =>
{
while (true)
{
var action = queue.Take();
action(resource);
}
});
//Now to do some work you simply add something to the queue...
queue.Add((sb) => sb.Append("Hello"));
queue.Add((sb) => sb.Append(" World"));
queue.Add((sb) => Console.WriteLine("Content: {0}", sb.ToString()));
Console.ReadLine();
}这一切都是静态的,有点丑陋,当然需要返工,但应该是可以的。这样做的想法是,您要执行的lambdas队列,它们将被一个接一个地执行,这样您就不必在资源上进行同步。
https://stackoverflow.com/questions/9499130
复制相似问题