c++/cli c# winforms 跨线程操作有时可能
c++/cli c# winforms cross-thread operation sometimes possible
我正在使用 c++/cli(应该也适用于 c#)并创建一个 winforms 程序。
我有几行代码可以在 DataGridView 中编辑数据。代码由 FileSystemWatcher 事件执行,但它可以由后台工作程序或简单线程执行。但是,它不是由 UI 线程执行的。
DGV 放置在 TabControl 的选项卡上。当包含 DGV 的选项卡具有焦点时执行代码时,代码将失败并出现众所周知的预期异常“跨线程操作无效”。
但是当另一个选项卡获得焦点时,代码执行顺利。我假设 DGV 在未显示时未更新,导致代码在这种情况下运行良好。但这意味着向消息队列发送 WM_PAINT 之类的消息取决于 DGV 的可见性(显示或不显示),如果不可见,则必须在再次显示 DGV 时发送这些消息.
这是正确的吗?
当(不)显示 DGV 时,代码执行有何不同?
您的代码根本上是错误的,但这并不意味着您一定会被提醒。当控件不可见时它不会爆炸,不需要更新它所以不需要做任何线程不安全的事情所以没有例外。
您必须解决根本问题。用FileSystemWatcher::SynchronizingObject属性很容易做到。只需在表单构造函数中将其设置为 this 即可。现在,该事件会在 UI 线程上自动引发,您可以参与控制属性而无需担心。修复:
MyForm(void)
{
InitializeComponent();
fileSystemWatcher1->SynchronizingObject = this;
}
假设您已将 FSW 从工具箱中拖放到表单中。根据需要进行调整。
我正在使用 c++/cli(应该也适用于 c#)并创建一个 winforms 程序。
我有几行代码可以在 DataGridView 中编辑数据。代码由 FileSystemWatcher 事件执行,但它可以由后台工作程序或简单线程执行。但是,它不是由 UI 线程执行的。
DGV 放置在 TabControl 的选项卡上。当包含 DGV 的选项卡具有焦点时执行代码时,代码将失败并出现众所周知的预期异常“跨线程操作无效”。
但是当另一个选项卡获得焦点时,代码执行顺利。我假设 DGV 在未显示时未更新,导致代码在这种情况下运行良好。但这意味着向消息队列发送 WM_PAINT 之类的消息取决于 DGV 的可见性(显示或不显示),如果不可见,则必须在再次显示 DGV 时发送这些消息.
这是正确的吗?
当(不)显示 DGV 时,代码执行有何不同?
您的代码根本上是错误的,但这并不意味着您一定会被提醒。当控件不可见时它不会爆炸,不需要更新它所以不需要做任何线程不安全的事情所以没有例外。
您必须解决根本问题。用FileSystemWatcher::SynchronizingObject属性很容易做到。只需在表单构造函数中将其设置为 this 即可。现在,该事件会在 UI 线程上自动引发,您可以参与控制属性而无需担心。修复:
MyForm(void)
{
InitializeComponent();
fileSystemWatcher1->SynchronizingObject = this;
}
假设您已将 FSW 从工具箱中拖放到表单中。根据需要进行调整。