i want to get property of some control, from another thread. for instance
string s = textBox1.Text;
and i'm getting exception about unsafe threading. in case when i set property, its clear for me, i call invoke, like
textBox1.Invoke(new MethodInvoker..bla开发者_JS百科blabla
but what i can do with "get"?
You should use invoke for the get too:
string text = null;
someControl.Invoke((MethodInvoker) delegate {
text = someControl.Text;
});
Thread-affinity affects all operations; not just writes. Another thread could be in the middle of changing something. For a string you would probably fluke it either way (due to atomic reference reads), but this shouldn't be abused; use Invoke.
If possible, read the value of the TextBox from the GUI thread, before you started your background thread, and send this value to the background thread as a parameter.
It is usually desirable to separate between the UI and the business logic, and you can benefit from designing your background tasks in a way that they are not aware of any UI component.
If you must access UI values from the background thread after all, you can still use Invoke
or BeginInvoke
to get the value from the TextBox.
You can safely read values without the need of Invoke, but I would recommend not to. Just centralize all your GUI read/writes into the main thread. Pass all the necessary values to the background thread so that it can perform the task. This background thread shouldn't know anything about the GUI, it should get some input, process it and produce a result which would be passed using the Invoke
method so that it can be interpreted by the GUI. This is for the sake of reusability. Imagine tomorrow switching to some other GUI like a console application or WPF, if your background thread code is mixed with GUI access you won't be able to easily reuse it.
Also you might take a look at BackgroundWorker which provides convenient events so that you don't need to manually marshal calls to the main thread with Invoke
.
精彩评论