首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >强制单线程访问资源。

强制单线程访问资源。
EN

Stack Overflow用户
提问于 2012-02-29 12:24:20
回答 1查看 3.9K关注 0票数 4

目前,我在一个只能从一个线程访问的项目中拥有多个资源。一个例子是ZeroMQ服务器,另一个例子是三菱PLC通信模块,这不是线程安全。

现在,我为任何需要单线程访问的资源创建一个单独的线程。我没有将它封装在类或任何东西中,所以我在每个类中都有一个ThreadStart (void)方法和几个属性,需要对资源进行协调访问。然后,我使用与Invoke / BeginInvoke相结合的dispatcher强制从单独线程进行访问。

是否已有一些类可以协调从单个线程对资源的访问?

下面是一些示例代码,现在可以为我找到一个分配器:

代码语言:javascript
复制
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(...);

我可以将这些代码包装在类中,以便在需要时创建线程和调度程序,但我无法想象这是协调对线程不安全资源的访问的最佳解决方案。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-02-29 14:30:09

你试过使用任务BlockingCollection吗?您可以在需要访问资源的任务中排队,并启动一个任务来排队列并运行该任务,然后一个接一个地运行,这样就没有竞争条件了?

代码语言:javascript
复制
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队列,它们将被一个接一个地执行,这样您就不必在资源上进行同步。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9499130

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档