Why only the thread that created UI control can access it [duplicate] - c#

I know that if I am modifying a control from a different thread, I should take care because WinForms and WPF don't allow modifying control's state from other threads.
Why is this restriction in place?
If I can write thread-safe code, I should be able to modify control state safely. Then why is this restriction present?

Several GUI frameworks have this limitation. According to the book Java Concurrency in Practice the reason for this is to avoid complex locking. The problem is that GUI controls may have to react to both events from the UI, data binding and so forth, which leads to locking from several different sources and thus a risk of deadlocks. To avoid this .NET WinForms (and other UIs) restricts access to components to a single thread and thus avoids locking.

In the case of windows, when a control is created UI updates are performed via messages from a message pump. The programmer does not have direct control of the thread the pump is running on, therefore the arrival of a message for a control could possibly result in the changing of the state of the control. If another thread (that the programmer was in direct control of) were allowed to change the state of the control then some sort of synchronization logic would have to be put in place to prevent corruption of the control state. The controls in .Net are not thread safe; this is, I suspect by design. Putting synchronization logic in all controls would be expensive in terms of designing, developing, testing and supporting the code that provides this feature. The programmer could of course provide thread safety to the control for his own code, but not for the code that is in .Net that is running concurrently with his code. One solution to this issue is to restrict these types of actions to one thread and one thread only, which makes the control code in .Net simpler to maintain.

.NET reserves the right to access your control in the thread where you created it at any time. Therefore accesses that come from another thread can never be thread safe.

You might be able to make your own code thread-safe, but there is no way for you to inject the necessary synchronization primitives into the builtin WinForm and WPF code that match up with the ones in your code. Remember, there are a lot of messages getting passed around behind the scenes that eventually cause the UI thread to access the control without you really ever realizing it.
Another interesting aspect of a controls thread affinity is that it could (though I suspect they never would) use the Thread Local Storage pattern. Obviously if you accessed a control on a thread other than the one it was created on it would not be able to access the correct TLS data no matter how carefully you structured the code to guard against all of the normal problems of multithreaded code.

Windows supports many operations which, especially used in combination, are inherently not thread-safe. What should happen, for example, if while one thread is trying to insert some text into a text field starting with the 50th character, while another thread tries to delete the first 40 characters from that field? It would be possible for Windows to use locks to ensure that the second operation couldn't be begun until the first one completed, but using locks would add overhead to every operation, and would also raise the possibility of deadlock if actions on one entity require manipulation of another. Requiring that actions involving a particular window must happen on a particular thread is a more stringent requirement than would be necessary to prevent unsafe combinations of operations from being performed simultaneously, but it's relatively easy to analyze. Using controls from multiple threads and avoiding clashes via some other means would generally be more difficult.

Actually, as far as I know, that WAS the plan from the beginning! Every control could be accessed from any thread! And just because thread locking was needed when another thread required access to the control --and because locking is expensive-- a new threading model was crafted called "thread rental". In that model, related controls would be aggregated into "contexts" using only one thread, thus reducing the amount of locking needed.
Pretty cool, huh?
Unfortunately, that attempt was too bold to succeed (and a bit more complex because locking was still required), so the good old Windows Forms threading model --with the single UI thread and with the creating thread to claim ownership of the control-- is used once again in wPF to make our lives ...easier?

Related

C# Threading - Using a class in a thread-safe way vs. implementing it as thread-safe

Suppose I want to use a non thread-safe class from the .Net Framework (the documentation states that it is not thread-safe). Sometimes I change the value of Property X from one thread, and sometimes from another thread, but I never access it from two threads at the same time. And sometimes I call Method Y from one thread, and sometimes from another thread, but never at the same time.
Is this means that I use the class in a thread-safe way, and the fact that the documentation state that it's not thread-safe
is no longer relevant to my situation?
If the answer is No: Can I do everything related to a specific object in the same thread - i.e, creating it and calling its members always in the same thread (but not the GUI thread)? If so, how do I do that? (If relevant, it's a WPF app).
No, it is not thread safe. As a general rule, you should never write multi threaded code without some kind of synchronization. In your first example, even if you somehow manage to ensure that modifying/reading is never done at the same time, still there is a problem of caching values and instructions reordering.
Just for example, CPU caches values into a register, you update it on one thread, read it from another. If the second one has it cached, it doesn't go to RAM to fetch it and doesn't see the updated value.
Take a look at this great post for more info and problems with writing lock free multi threaded code link. It has a great explanation how CPU, compiler and CLI byte code compiler can reorder instructions.
Suppose I want to use a non thread-safe class from the .Net Framework (the documentation states that it is not thread-safe).
"Thread-safe" has a number of different meanings. Most objects fall into one of three categories:
Thread-affine. These objects can only be accessed from a single thread, never from another thread. Most UI components fall into this category.
Thread-safe. These objects can be accessed from any thread at any time. Most synchronization objects (including concurrent collections) fall into this category.
One-at-a-time. These objects can be accessed from one thread at a time. This is the "default" category, with most .NET types falling into this category.
Sometimes I change the value of Property X from one thread, and sometimes from another thread, but I never access it from two threads at the same time. And sometimes I call Method Y from one thread, and sometimes from another thread, but never at the same time.
As another answerer noted, you have to take into consideration instruction reordering and cached reads. In other words, it's not sufficient to just do these at different times; you'll need to implement proper barriers to ensure it is guaranteed to work correctly.
The easiest way to do this is to protect all access of the object with a lock statement. If all reads, writes, and method calls are all within the same lock, then this would work (assuming the object does have a one-at-a-time kind of threading model and not thread-affine).
Suppose I want to use a non thread-safe class from the .Net Framework (the documentation states that it is not thread-safe). Sometimes I change the value of Property X from one thread, and sometimes from another thread, but I never access it from two threads at the same time. And sometimes I call Method Y from one thread, and sometimes from another thread, but never at the same time.
All Classes are by default non thread safe, except few Collections like Concurrent Collections designed specifically for the thread safety. So for any other class that you may choose and if you access it via multiple threads or in a Non atomic manner, whether read / write then it's imperative to introduce thread safety while changing the state of an object. This only applies to the objects whose state can be modified in a multi-threaded environment but Methods as such are just functional implementation, they are themselves not a state, which can be modified, they just introduce thread safety for maintaining the object state.
Is this means that I use the class in a thread-safe way, and the fact that the documentation state that it's not thread-safe is no longer relevant to my situation? If the answer is No: Can I do everything related to a class in the same thread (but not the GUI thread)? If so, how do I do that? (If relevant, it's a WPF app).
For a Ui application, consider introducing Async-Await for IO based operations, like file read, database read and use TPL for compute bound operations. Benefit of Async-Await is that:
It doesn't block the Ui thread at all, and keeps Ui completely responsive, in fact post await Ui controls can be directly updated with no Cross thread concern, since only one thread is involved
The TPL concurrency too makes compute operations blocking, they summon the threads from the thread Pool and can't be used for the Ui update due to Cross thread concern
And last: there are classes in which one method starts an operation, and another one ends it. For example, using the SpeechRecognitionEngine class you can start a speech recognition session with RecognizeAsync (this method was before the TPL library so it does not return a Task), and then cancel the recognition session with RecognizeAsyncCancel. What if I call RecognizeAsync from one thread and RecognizeAsyncCancel from another one? (It works, but is it "safe"? Will it fail on some conditions which I'm not aware of?)
As you have mentioned the Async method, this might be an older implementation, based on APM, which needs AsyncCallBack to coordinate, something on the lines of BeginXX, EndXX, if that's the case, then nothing much would be required to co-ordinate, as they use AsyncCallBack to execute a callback delegate. In fact as mentioned earlier, there's no extra thread involved here, whether its old version or new Async-Await. Regarding task cancellation, CancellationTokenSource can be used for the Async-Await, a separate cancellation task is not required. Between multiple threads coordination can be done via Auto / Manual ResetEvent.
If the calls mentioned above are synchronous, then use the Task wrapper to return the Task can call them via Async method as follows:
await Task.Run(() => RecognizeAsync())
Though its a sort of Anti-Pattern, but can be useful in making whole call chain Async
Edits (to answer OP questions)
Thanks for your detailed answer, but I didn't understand some of it. At the first point you are saying that "it's imperative to introduce thread safety", but how?
Thread safety is introduced using synchronization constructs like lock, mutex, semaphore, monitor, Interlocked, all of them serve the purpose of saving an object from getting corrupt / race condition. I don't see any steps.
Does the steps I have taken, as described in my post, are enough?
I don't see any thread safety steps in your post, please highlight which steps you are talking about
At the second point I'm asking how to use an object in the same thread all the time (whenever I use it). Async-Await has nothing to do with this, AFAIK.
Async-Await is the only mechanism in concurrency, which since doesn't involved any extra thread beside calling thread, can ensure everything always runs on same thread, since it use the IO completion ports (hardware based concurrency), otherwise if you use Task Parallel library, then there's no way for you to ensure that same / given thread is always use, as that's a very high level abstraction
Check one of my recent detailed answer on threading here, it may help in providing some more detailed aspects
It is not thread-safe, as the technical risk exists, but your policy is designed to cope with the problem and work around the risk. So, if things stand as you described, then you are not having a thread-safe environment, however, you are safe. For now.

Expected cross-thread exception in a C# WinForms application did not occur

I'm coming from WPF and I am new to WinForms. While investigating a cross-threading situation, a cross-thread exception that I expected did not occur.
Here is a basic summary of my situation. There is one Label control named label1 and one Button named button1. The click event handler for button1 essentially looks like this:
private void button1_Click(object sender, EventArgs e)
{
Task.Factory.StartNew(()=>
{
label1.Text = "Some-Other-New-Text";
});
}
This is not throwing a cross-thread exception as I expect it to. Is this because WinForms applications do not have cross-threading problems? Note that I have investigated this in Visual Studio 2013 as well as in Visual Studio 2010.
Windows forms work on top of the Windows messaging infrastructure. That means that a lot of the operations you perform on the controls in question are actually delegated to Windows to support proper native behaviour of all the controls.
Label doesn't change the default implementation, and it doesn't cache the text in managed code by default. This means that it uses the SetWindowText native method to set the current label text (and correspondingly, GetWindowText to read it), which posts a WM_SETTEXT to the message loop. The real update happens on the thread that handles the message loop, also known as the UI thread. Unless you go out of your way to prohibit this kind of call (Control.checkForIllegalCrossThreadCall in current reference source), it will work. By default, this is set depending on whether a debugger is attached - so your code may crash while debugging, but will work outside of a debugger, since SetWindowText happens to be thread-safe. There's other parts of the Text property that may or may not be thread-safe, but if you're lucky, everything works just fine.
You can set Control.CheckForIllegalCrossThreadCall to true explicitly, and I'd recommend you to do so. Accessing any resource from multiple threads is prone to hard to debug issues, and marshalling whatever work needs to be done on the UI to the UI thread is... kind of the job of the UI thread anyway.
Manipulating the UI exclusively from the UI thread gives you quite important benefits:
Predictability and realiability - things will tend to happen in certain reliable orders. If I have a hundred threads setting the Textof two different controls, delegating the UI update to the UI thread will ensure that the two controls always have consistent values, while updating directly from the background threads will tend to interleave the updates "randomly". In a real application, this can cause confusion as well as hard to find bugs. Note that this isn't absolute - any await/Application.DoEvents may or may not disrupt this. But even in that case, you have well defined synchronization points, rather than preëmptive multi-tasking.
Multi-threading is hard. Most things you work with aren't thread-safe, and even allegedly thread-safe operations may have multi-threading bugs or simply complicated behaviour when running in a MT scenario. Even a simple thing like updating two booleans in a sequence becomes dangerous, and may introduce hard to debug bugs. Your best bet is to keep as many things thread-affine as you can. You'll usually find you can confine all interfaces between the threads to a tiny portion of your code, which makes them much easier to test and debug.
It's really cheap when you've already separated "work" from "UI" anyway. And that's a pretty handy design practice on its own.
As a side-note, you usually want to await tasks that you spin off, or handle exceptions explicitly. If you enable Control.CheckForIllegalCrossThreadCall, the label will no longer update, but it will not show an exception either - by default, threadpool threads ignore unhandled exceptions nowadays (since .NET 4.5.2 IIRC). The await will marshall any exceptions (and return values) back to the UI thread.
In my situation, I expected a cross-thread exception (in the debugger†) in my WinForms application when accessing a ToolStripStatusLabel from a thread other than the UI thread.
I discovered that the reason that the cross-thread exception does not occur is because ToolStripStatusLabel does not derive from System.Windows.Forms.Control and therefore does not have a CheckForIllegalCrossThreadCalls property.
(I was able to narrow this down by first proving that attempting to access a TextBox in a non-UI thread did raise the cross-thread exception.)
† See this answer as to why WinForms cross-thread exceptions typically happen only when you are debugging.

Hosting Controls over Multiple Threads in .Net

I have a problem and after three days I still can not find a answer.
I am creating a usercontrol. This control has two controls hosted on it. One is an edit field and the other is a margin that will hold line numbers and other user added stuff.
What I am trying to do is instantiate these to separate controls in their own threads and perform all tasks on these threads eg painting and updating. The usercontrol thread will simply filter messages and direct same to the correct control. I will be doing this by overriding the WndProc method.
Doing all the message stuff I am fine with however how do I instantiate the controls. Once the thread that creates these controls finishes wont the threads die and the controls became inaccessible. Sorry no code at the moment, I tend to do a lot of research before any coding but I can't seem to find anything that can be of help.
This is not going to work very well. All UI elements (forms, controls, etc.) have thread affinity requirements that dictate that they can only ever be accessed from the thread that created them. Trying to embed a control hosted on one thread in another control from another thread is an effort in futility. Even if you can get it work (and use the term "work" loosely here) the results may be unpredictable at best. You need to rethink your approach. It would be much better to host all of the controls on the same thread and then shuttle off any time consuming operations to a worker thread. Remember, keep the worker thread busy with non-UI related operations only. Once the operation is complete then you can marshal over the results to the UI thread where it can dispatched appropriately to the controls.

Isn't blindly using InvokeRequired just bad practice?

I am a novice programmer so I could be completely mistaken here, but this issue bugs me more then it should.
This is actually a follow-up from this question.
The accepted answer was, that you have to call InvokeRequired in order to avoid some overhead, because there is a chance you are already operating on the UI thread.
In theory, I agree that it could save some time. After some tests I found out that using Invoke takes about twice the time compared to calling an operation normally (tests like setting the text of a label n times, or placing a very, very big string in a RichTextBox).
But! Then there is practice.
MSDN documentation says:
This property can be used to determine if you must call an invoke method, which can be useful if you do not know what thread owns a control.
In most cases, you do know when you try to access a control from another thread. Actually the only situation I can think of is, when the control is accessed from a method that can be called by thread X aswell as the owner thread. And that to me is a very unlikely situation.
And even if you genuinely don't know which thread tries to manipulate the control, there is the fact that the UI thread doesn't have to be updated that frequently. Anything between 25-30 fps should be okay for your GUI. And most of the changes made in the UI-controls takes far less then milliseconds to perform.
So if I understand corrrectly, the only scenario where you have to check if an invoke is required is when you don't know which thread is accessing the control and when the GUI update takes more than about 40 ms to finish.
Then there is the answer to this question I asked on http://programmers.stackexchange.com. Which states that you shouldn't be busy with premature optimisation when you don't need it. Especially if it sacrifices code readability.
So this brings me to my question: shouldn't you just use invoke when you know a different thread accesses a control, and only when you know your UI thread can access that piece of code and you find that it should run faster, that you should check if an Invoke is required?
PS: after proofreading my question it really sounds like I am ranting. But actually I am just curious why InvokeRequired is seemingly overused by many more-experienced-than-me programmers.
You are taking things out of context here. The first question you linked linked another question which specifically was about writing a thread-safe method to access a UI control.
If you don't need a thread-safe access to a UI control, because you know you won't update it from another thread, then certainly, you shouldn't employ this technique. Simply update your UI control without using InvokeRequired or Invoke.
On the other hand, if the call will always originate in a thread other than the UI thread, simply use Invoke without first checking for InvokeRequired.
This leads to three simple rules:
If you update the control only from the UI thread, use neither InvokeRequired nor Invoke
If you update the control only from a thread other than the UI thread, use only Invoke.
If you update the control from both the UI thread and other threads, use Invoke in combination with InvokeRequired.
In practice people tend to call the same method from both the foreign and the owning thread. The usual pattern is that the method itself determines whether the thread is the owning thread. If it is, it executes the follow-up code. If it isn't the method calls its own self using Invoke this time.
One benefit of this is that it makes the code more compact, as you have one method related to the operation instead of two.
Another and probably more important benefit is that it reduces the chance that the cross thread exception will be raised. If both methods were available at any time and both threads could choose any of the two, then there would be a chance of a seemingly legitimate method call raising an exception. On the other hand, if there's only one method that adapts to the situation, it provides a safer interface.

Proper way to pass GUI values to backgroundworker?

I am working with a fairly complex GUI and am trying to pass a lot of data from the GUI to a backgroudWorker. The problem I am running into is accessing some of the GUI values from the background worker. For example, if I try to get ComboBox.Text I get a InvalidOperationException due to cross-threading. However, if I say do TextBox.Text, everything seems to work fine. Granted I am fairly new to C#, so I'm a little unclear on why some of these are OK and others fail.
I have come up with several ways to fix my issues but am seeking the best practice from someone who is experienced in c#.
Here are a couple ways i can think of fixing this
create class/struct of all the values you want to pass to the background worker and pass this when you call RunworkAsync. I did not find this very attractive as i was having to build a class/struct for every page on my GUI to pass to the backgroundWorker
Create a bunch of different background workers that had specific task. I still had some issues with passing data but the amount of data I had to pass was cut down quite a bit. However, the number of DoWork/ProgressChanged/RunworkerCompleted went up significantly which was less than ideal.
(this lead me to what I'm currently doing)
create a delegate and method to capture the information
private delegate string ReadComboDelegate(ComboBox c);
private string ReadComboBox(ComboBox c)
{
if(c.InvokeRequired)
{
ReadComboDelegate del = new ReadComboDelegate(this.ReadComboBox);
return (string) c.Invoke(del,c);
}
else
{
return c.Text
}
}
then within DoWork, do somthing like string txt = this.ReadComboBox(this.comboBox1);
When you have a simple GUI and you don't have to pass a lot of data this is pretty simple problem. However, the more items and complex the GUI gets the bigger this problem becomes. If anyone has any info that would make this easier, I would appreciate it.
Thanks
The Cross Threading issue you are running into is due to the requirement that only the UI thread is allowed to "touch" UI controls.
I think that the most agreed upon method of passing data to a background worker is your solution #1 - create a simple structure that contains all of the data needed to perform the processing.
This is much simpler than creating ReadXXX methods for every control in the UI, and it defines what the background process needs to perform its task...
It is rather by accident that TextBox doesn't cause this exception. Its Text property is cached in a string. That's not the case for ComboBox.Text, and the vast majority of other control properties, it asks the native Windows control and at that point Windows Forms discovers that you are trying to use a control from a thread other than the UI thread. No can do.
You definitely need to think of a way to restructure this code. It is not only illegal, it is incredibly expensive and fundamentally thread unsafe since the UI could be updated while your worker is running. Collect the info from the controls you need into a little helper class, pass that as an argument to the RunWorkerAsync(object) overload. And get it back in DoWork from e.Argument.
I would definitely avoid #3. Despite the fervor over using Control.Invoke to coordinate worker and UI threads it is often overused and is usually a suboptimal strategy at best. I much prefer #1 and #2 over #3. Here are the reasons why I tend to avoid #3.
It tightly couples the UI and worker threads.
The worker thread gets to dictate how much work the UI thread performs.
The worker thread has to wait for the UI thread to respond before proceeding.
It is an expensive operation.
I know it may require some additional upfront effort on your part to get #1 or #2 going, but the end result will be better in the long run.
As a corollary to my answer the Control.Invoke method tends to be overused when data needs to follow the opposite direction as well (from worker thread to UI thread as in the case of sending progress information to the UI). Sadly this is the method that BackgroundWorker uses internally with its ReportProgress method. It is usually better to have the UI thread poll a shared data structure for this information for some of the same reasons as above plus:
The UI thread gets to dictate when and how often the update should take place.
It puts the responsibility of updating the UI thread on the UI thread where it should belong anyway.
There is no risk of the UI message pump being overrun as would be the case with the marshaling techniques initiated by the worker thread.
However, with that said I am not suggesting that you abandon BackgroundWorker entirely. Just keep some of these points in mind.

Categories