我试图从两个线程访问ListBox。我使用两个锁定语句,但这不起作用。
我的代码:
public partial class Form1 : Form
{
private List<LogInfo> logs = new List<LogInfo>();
private static Object lockObj = new Object();
private static Object lockObj0 = new Object();
/* ... */
void fileSystemWatcher_Renamed(object sender, RenamedEventArgs e)
{
try
{
ToggleWatcher(false);
LogInfo logInfo = new LogInfo(e.ChangeType, GetCurrentTime(), e.FullPath, e.OldName, e.Name);
lock (lockObj)
{
logs.Add(logInfo);
listBox1.Items.Add(logInfo.ToString());
}
}
finally
{
ToggleWatcher(true);
}
}
void fileSystemWatcher_Detect(object sender, FileSystemEventArgs e)
{
try
{
ToggleWatcher(false);
LogInfo logInfo = new LogInfo(e.ChangeType, GetCurrentTime(), e.FullPath);
lock (lockObj)
{
logs.Add(logInfo);
// Here in below line i get error: invalidoperationexception was unhandled
listBox1.Items.Add(logInfo.ToString());
}
}
finally
{
ToggleWatcher(true);
}
}
}
我不知道为什么它不起作用(我有两个锁定语句),但我收到错误:invalidoperationexception未处理
我尝试将lockObj更改为静态或使用Monitor类,但我仍然得到同样的错误
答案 0 :(得分:-1)
您没有说出异常消息是什么,但我认为问题是您正在尝试从另一个线程访问UI(当您向listBox1
添加项目时)。它与锁定无关;它只是允许UI线程访问UI。如果需要这样做,则必须使用Invoke
:
this.Invoke(new Action(() => listBox1.Items.Add(logInfo.ToString())));
另外,请注意,在UI线程上锁定和调用操作非常昂贵;当您处理来自FileSystemWatcher
的事件时,您必须尽快执行此操作,否则存在FileSystemWatcher
缓冲区溢出且您错过事件的风险。一种常见的方法是将事件附加到事件处理程序中的线程安全集合,并在另一个线程上处理它们。