Write from the background thread, read from the UI one
I have a background thread doing some work and a UI displaying the progress, and for various reasons, I'm not using a background worker; instead, a Timer
triggers updates to the UI.
I'm not using Invoke
calls at all. Instead, the background process writes to an array of 4 strings. This array is declared as an instance member of my main form.
Do I need to use locks to read this array from the UI thread? Is it fine to write to the array from the background thread and read开发者_如何学JAVA from it from the UI one without any extra precautions?
EDIT: MSDN reads "The lock keyword marks a statement block as a critical section by obtaining the mutual-exclusion lock for a given object, executing a statement, and then releasing the lock."
. Doesn't that mean that the lock will only prevent the same block of code from being run by two different threads?
Have you thought about what will happen if the reader is reading and the writer modifies it?
You should use lock
, both in the reader and the writer.
If you are accessing & modifying any other resource from different threads, the same. You should lock on the same object to avoid secondary effects...
The best reference I have found about threading in general in C# is the following book:
Threading in C#, by Joseph Albahari
You will find there lots of examples like that one.
You can read it online, and I suggest you to do it, because it takes many topics related to multithreading, like Monitor.Enter
and others
Edit:
If you are storing data in a local variable only because you will access to it by the main thread later, I don't think that is the best option at all. You can modify your controls in the GUI without problem using another threads, and it isn't difficult at all:
Instead of doing:
public void UpdateTextBox(string text) {
textBox1.Text = text;
}
you can do:
public void UpdateTextBox(string text) {
MethodInvoker m = () => { textBox1.Text = text; };
//The following lines can be encapsulated in a method, in case you need to use it again in other methods...
if (InvokeRequired) {
BeginInvoke(m);
}
else {
m.Invoke();
}
}
The quick answer is that you need to use locks if you have multiple threads that are writing to your array of strings at the same time. Here is a link to the latest reference on locks for c# http://msdn.microsoft.com/en-us/library/c5kehkcz%28v=VS.100%29.aspx.
Just to clarify, as i saw your comment, you must use a lock statement around the write operation AND a another lock statements around the reader satements. i.e.
//lock sync object in your form
private object sync = new object();
in the writing method and in the reading method.
lock (sync)
{
//access the array here
}
精彩评论