问题
I am using c++/cli (should also apply to c#) and creating a winforms program.
I have some lines of code that edit data in a DataGridView. The code is executed by an FileSystemWatcher event, but it could be executed by a background worker or a simple thread. However, it is NOT executed by the UI thread.
The DGV is placed on a tab of a TabControl. When the code is executed while the DGV-containing tab has the focus, the code fails with the well-known and expected exception "Cross-thread operation not valid".
But when another tab has the focus, the code executes smoothly. I assume that the DGV is not updated when it's not shown, causing the code to work well in this case. But this means that the sending of messages like WM_PAINT to the message queue depends on the visibility (shown or not) of the DGV, and in case it is not visible, those messages must be sent when the DGV gets shown again.
Is this correct?
What are the differences in code exection when the DGV is (not) shown?
回答1:
Your code is fundamentally wrong, but that does not mean that you are guaranteed to be reminded about it. It won't bomb when the control is not visible, no need to update it so no need to do anything that's thread-unsafe so no exception.
You must fix the underlying problem. Very easy to do with the FileSystemWatcher::SynchronizingObject property. Just set it to this in the form constructor. Now the event is automatically raised on the UI thread and you can party on the control properties without being rapped on the knuckles. Fix:
MyForm(void)
{
InitializeComponent();
fileSystemWatcher1->SynchronizingObject = this;
}
With the assumption that you dropped the FSW from the toolbox onto your form. Tweak as needed.
来源:https://stackoverflow.com/questions/29790014/c-cli-c-sharp-winforms-cross-thread-operation-sometimes-possible