这可能是一个基本问题,但我想知道我的编程是否被接受为良好做法: - )
我的代码由一个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()?
答案 0 :(得分:1)
我使用我的代码进行了不同的测试,似乎使用
没什么不好//setting callback function for 'hidden.bs.modal' event
$('#modal').on('hidden.bs.modal', function(){
//remove the backdrop
$('.modal-backdrop').remove();
})
但是从多个线程读取/写入Socket实际上并不是一个好习惯。 所以我想我会有两把锁:
第一个将阻止同一个线程同时进入两个不同的方法(一个在正常的程序流程中,另一个在与invoke-patterns一起使用时)。