我正在开发一个C#4.5应用程序,其中许多线程需要访问相同的串行端口。
由于我也将在串口上收到回复,我想避免进一步写入,直到我收到回复并阅读它。
我有一个SerialHandler类,它是SerialPort类的包装器,write和read方法看起来像这样:
public void write(string message)
{
Monitor.Enter(lockingObject);
//Stuff
serialPort.write(message);
}
public string read()
{
//Reading procedure
Monitor.Exit(lockingObject);
}
但是一旦我从表单发出写入,我就会得到SynchronizationLockException,说“从非同步的代码块中调用了对象同步方法”。 lockingObject是一个私有且只读的Object变量。
如何避免此错误? 非常感谢
编辑,它应该像这样工作:
线程A获得读/写权限
线程B尝试获取访问但未通过
线程A得到阅读,所以他释放了他的锁
线程B现在可以执行写入,获取锁定,读取和删除锁定
答案 0 :(得分:0)
引发异常,因为不同的线程是trying to release the object。
这是解决问题的简单方法:
class MySerialPort
{
private AutoResetEvent _waithandle = new AutoResetEvent(true);
private SerialPort _serialPort;
public void write(string message)
{
_waithandle.WaitOne();
//Stuff
_serialPort.Write(message);
}
public string read()
{
try
{
...
...
}
finally
{
_waithandle.Set();
}
}
}
第一个线程将写入,然后任何新的写操作将被阻塞,直到读取将释放其中一个。
修改强>
我在下面的评论中看到你正在寻找最快的解决方案。 根据这个link,下面的代码将在60ns(在英特尔酷睿i7 860上)完成工作,这要好得多
class MySerialPort
{
private ManualResetEventSlim _waithandle = new ManualResetEventSlim(true);
private SerialPort _serialPort;
private readonly object _sync = new object();
public void write(string message)
{
lock (_sync)
{
_waithandle.Wait();
//Stuff
_serialPort.Write(message);
_waithandle.Reset();
}
}
public string read()
{
try
{
....
}
finally
{
_waithandle.Set();
}
}
}
答案 1 :(得分:-2)
你可以使用Mutex
class SerialHandler
{
private Mutex _mutex = new Mutex();
private SerialPort _serialPort;
public void write(string message)
{
_mutex.WaitOne();
//Stuff
_serialPort.write(message);
}
public string read()
{
//Reading procedure
_mutex.ReleaseMutex();
}
}
问题意味着您已尝试释放未获得的锁定。