从不同的线程

时间:2016-06-15 18:15:46

标签: c# locking

这可能是一个基本问题,但我想知道我的编程是否被接受为良好做法: - )

我的代码由一个c#通信类组成,它使用底层的tcp套接字对象。但它也可能是支持打开,关闭,读写访问的任何其他对象。

单个通信包括发送电报并等待来自另一方的答案。

到目前为止,我只从一个线程中访问了这个c#类,它运行正常。今天我用几个并行的工作线程测试它,在一个表单类中创建并从表单类开始,通信对象是表单类中的一个对象。线程(只是表单类的一个方法)可以随时访问通信对象。

但不幸的是,由于没有锁定,一个线程可以收到另一个线程的答复电报。 要解决这个问题,我只需将所有调用函数放在lock(){}语句中:

public Boolean Read(UInt16 adress,out UInt16 value)
{
    lock(this)
    {
        // send the read telegram and receive 
        // an ACK Telegram with the data
        value = _connection.Read(adress);
    }
 }

public Boolean Write(UInt16 adress,UInt16 value)
{
    lock(this)
    {
        // send the Write telegram and receive 
        // an ACK Telegram with the data
        return _connection.Write(adress,value);
    }
 }

此示例中的代码与实际代码不相似,但lock()是有趣的。 我现在的问题是:

  • 锁机制是否足够强大?
  • 如果有多个线程正在等待进入锁定,是否保证每个等待的线程都可以访问?在这种情况下,更快的线程不会阻止更慢的线程?
  • 编程某种调度程序是否可行,让线程一个接一个地访问对象?

[编辑注释#1的答案]
我无法提供更详细的源代码,因为它可以复杂地发布多个对象,用于协议细节,套接字封装以及所有这些。

  • 我的方法都使用对套接字的同步调用。
  • 每个方法发送一个数据(电报)并等待它到达完整的答复电报或套接字超时。

你写了一些关于排队的事情。我从来没有考虑到这一点。但是IIRC我库的原始实现(2000年以前很好的旧c ++代码)采取了某种排队方式来解决COM / DCOM通信中的这个问题。

也许我应该再看看这段代码。 我对类对象的多线程通信的另一个解决方案是同时使用多个类对象。然后每个线程都会使用自己的套接字连接,什么都不会混淆。

另一方面,通信另一端的目标服务器使用多线程方法处理每个套接字连接,然后使用某种锁定机制(Mutexes)和同步(Events)将并行电报排入串行队列服务器。

[编辑#2]
在第一个线程调用Write()时,不同方法中的锁(this)是否会阻止另一个线程调用Read()?

1 个答案:

答案 0 :(得分:1)

我使用我的代码进行了不同的测试,似乎使用

没什么不好
//setting callback function for 'hidden.bs.modal' event
$('#modal').on('hidden.bs.modal', function(){
  //remove the backdrop
  $('.modal-backdrop').remove();
})

但是从多个线程读取/写入Socket实际上并不是一个好习惯。 所以我想我会有两把锁:

  • 锁(这个){}
  • 检查Thread.CurrentThread.ManagedThreadId与构造函数中使用的那个。

第一个将阻止同一个线程同时进入两个不同的方法(一个在正常的程序流程中,另一个在与invoke-patterns一起使用时)。