I was debugging an application and somewhere in the code, a thread tries to reach a listbox that was created by another thread. On attempt to access the listbox, the application throws a "Cross-thread operation not valid: Control 'listbox' accessed from a thread other than the thread it was created on" exception while debugging. However, when I run this application's output in bin\Debug folder, I do not get an exception dialog and I can see that the listbox is successfully accessed from the non-owner thread, so this makes me think that there is a behavioral difference here, not just a suppressed exception. I can get past this exception in debugging with the following line in form_load event
Control.CheckForIllegalCrossThreadCalls = false;
But what is the reason behind this different behavior?
Yes, this is only checked when a debugger is attached. This was necessary because there was lots of .NET 1.x code that violated this rule. It is not an obvious one.
The bigger problem is that such code got away with it. Either by luck, not thinking too much about the occasional painting problems or by thinking that aborting the app when it deadlocked and restarting it once a day was acceptable. Because the programmer had no real hope of discovering the problem without a diagnostic.
Microsoft cares a lot about backward compat, even if it is buggy compat. The fix is excellent, even though it is sometimes wrong (Show(owner) is checked when it shouldn't). And sometimes overlooks to check when it is code in the framework that violates the rule. Which happens when the thread dependency is indirect. Most common cases of that are updating the data source of a data-bound control in a worker thread (unbind first!) and using a control that listens for the SystemEvents.UserPreferenceChanged event (don't create UI on a second thread!)
For reference, the relevant code is present in the static constructor of the Control class:
static Control()
{
//...
checkForIllegalCrossThreadCalls = Debugger.IsAttached;
//...
}
Related
I'm trying to view the content of a List<> during debugging. Unfortunately I can't see them, cause I get the following message within the variables window:
corvalue.GetExactTypeSafe(out type). The object is in a
zombie state. (Exception of HRESULT: 0x8013134F). The error code is
CORDBG_E_OBJECT_NEUTERED, or 0x8013134F.
Does someone know what this means and how I can view the List<>? It's no compilation error cause I can normally run through the code.
sounds like you are using multi-threading. lets start with zombie state.
zombie state is when a thread that was previously started (by another thread) finally finished it work. and additionally this thread didn't return the control to the calling thread. hence, this thread is currently ain't doing anything although it wasn't terminated.This is the source of the name, the thread ain't alive and ain't dead. For more information you can check this post.
You need to simply free up all allocated resources by restarting your program or kill the parent thread\process.
If you keep having the issue in the "interesting code" You can also try to run your program with out multi threading to ensure you wouldn't encounter any zombies along the way. (:
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.
I have several System.Threading.Timers on my form application with callbacks that update the UI...successfully - i.e. without throwing errors.
I had built these earlier, before I knew that UI should not be updated on any thread other than the UI thread.
Now I am confused as to why it does not throw cross-thread exceptions when I am updating UI on these separate threading.timer threads?
I will be changing these callbacks so that the UI updates are invoked on UI thread, but I am curious as to why this works.
Edit: My application is a WinForms Application.
I will be changing these callbacks so that the UI updates are invoked on UI thread, but I am curious as to why this works.
If this is Windows Forms, it works purely by luck. Updating a UI on a background thread doesn't consistently work, but occasionally will not throw. In particular, if CheckForIllegalCrossThreadCalls is false, it will sometimes "work", and never throw - though the behavior is often wrong. Some controls do not always check every property, so some items "work" even though they're not always working correctly, as this typically introduces bugs that can be difficult to diagnose and correct later.
On a side note: If this were WPF, you could change the value of a item bound to your UI, effectively updating your UI, on a background thread. The WPF binding system will automatically marshal this to the UI thread for you. It does not work to change part of a collection, however.
I've also experienced this with WinForms. See here: Can you access UI elements from another thread? (get not set) It works by "magic" (read "in a random manner") in my opinion, and should not be taken as an invitation to do it in practice. It's by no means a thread-safe way of updating the GUI. Sometimes the program just does not complain.
In .NET 1.0 and 1.1, no cross-thread checking is performed, so you will never get an InvalidOperationException (although MSDN acknowledges that performing cross-thread updates “often leads to unpredictable results”, which may including application crashes).
In .NET 2.0 and later, cross-thread checking is performed depending on the value of the Control.CheckForIllegalCrossThreadCalls static property. Its default value is initialized from the Debugger.IsAttached static property (which indicates whether a debugger is attached to the process), meaning that cross-thread checking is not performed when the application is run on its own (without Visual Studio or any other debuggers attached to it).
This setting may, of course, be overridden by user code, including referenced libraries.
I believe this has to do with what type of Timer you are creating. There are two types:
System.Timers.Timer;
System.Windows.Forms.Timer
There is a distinct difference between these two, the System.Timers.Timer will throw exceptions if you update the UI, and the System.Windows.Forms.Timer will not. If you have a using statement :"Using System.Windows.Forms" and simply have a "Timer" this will be the Windows.Forms.Timer which is distinctly different from the System.Timers.Timer.
Under the hood (I believe) System.Windows.Forms.Timer is trapping a WM_TIMER message, so you are on the thread that is updating the GUI.
I am doing a project where I am loading several assemblies during runtime, for each of those assemblies I use reflection to find some specific classes, instantiate them and calling their methods. All this is working fine, but for some of the calls the process encounters a stack overflow which terminates my entire program. I don't have any control over the source code of the assemblies I am loading so I cant change the code I'm executing.
What I have tried to solve the problem:
I assign a thread to do the invocation of the methods and tried to
abort the thread after a timeintervall(I know that this is bad
practice but I cant change the code to terminate friendly). This
however doesn't work, I think the thread is to busy "stackoverflowing"
to handle the Abort-call.
Ive tried reducing the actual memory the thread has access to, this is not even a solution because you cant catch the stackoverflow-exception so my program terminates anyway (just quicker)
Questions:
Can a thread be to busy to be aborted? Is there some way to abort a thread that is having this behaviour?
How can we call code (that we don't have any control over) in a good way?
Thanks in advance!
The recommended procedure in case of "opaque code" is to actually fork a new process and start it. That way you gain two benefits:
If it fails by itself, it's isolated and won't take your main application down as well.
You can safely kill it and it won't cause as much trouble as an aborted thread.
I have an unhandled exception handler. It shows a nice GUI and allows users to send an error report. Users can even leave their name and phone number and things, and our support department calls them back. Works well, looks good, makes customers less angry. In theory, anyway.
The problem is that my application uses background threads, and the threads don't seem to care if an exception was thrown on, say, the GUI thread (which makes sense), and just continue their work. That eventually results in a WER dialog poping up if the user lets my custom exception handler window stay open long enough, making it look like the error handler itself crashed.
I don't have access to the thread objects in the scope of the exception handler, so I can't suspend them. Making the thread objects globally accessible is not a solution either. My workaround for now is to use something like Globals.Crashed = true; in my exception handler, and to have my thread methods check that property at every loop iteration. Not perfect, but it minimizes the damage.
Does anyone know a less-hacky method? Is my approach wrong? Do I have to do it like WER does and launch an external program that suspends the main program and shows the error UI?
If you have an unhandled, unknown exception, you can assume that ANYTHING has happend and that your program might fail to do even the most simple thing. Consider e.g. the case that it has consumed all available memory - then you won't be able to send the error report either, because it probably requires memory to be allocated.
A good approach is to write a separate small application that just does the error reporting. That application can pick up the details to report from a file. That way your unknown exception handler would:
Dump the info to a file in the temp directory.
Start the error reporting app with the file name as an argument.
Terminate the failing process, before it does something stupid.
The temp file should be removed by the error reporting app.
You could track all your threads in a global Collection object, so that when your handler executes, it could simply iterate through the collection object and abort the threads there.
Take a look at the code in this question, Suspend Process in C#, you'll need to tweak it so as to not suspend your GUI thread and any that aren't background ones you've started, but it should do the trick.
The better option, however, is to try and launch your error report GUI as a separate process, passing any required information to it, and then kill the original process from your unhandled exception handler, rather than allowing anything to run in a potentially corrupt state.