Why Is Cross Thread Operation Exception Not Thrown While Running Exe in Bin\Debug

Why is cross thread operation exception not thrown while running exe in bin\Debug

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;
//...
}

Why my .Net/WinForms application getting Cross Thread exceptions only in Visual Studio?


I only see these exceptions while debugging in Visual Studio.

Because CheckForIllegalCrossThreadCalls defaults to Debugger.IsAttached

Sample Image

Source Code link

I know in years past it was a BAD IDEA/DESIGN to do so and whenever we came across instances, we would wrap access with Invoke()/BeginInvoke()

You should still do so, or work out some other way of marshaling the work of updating the control onto the thread that created the control

Given these exceptions get "eaten" when running the application outside of Visual Studio, is this still the case?

It is still the case; fix these problems

or is it considered a benign/safe exception?

I don't recall ever coming across anyone who thought it was..

Why the cross-threading exception raises only when debugging?

Those exceptions are only checked is the debugger is attached to the process, so they don't show up when running the process without debugging (or standalone outside of VS).

This behavior can be controlled through CheckForIllegalCrossThreadCalls, a static property exposed on the Control class. I strongly advice against disabling it though, those exceptions are thrown to let the developer know something is potentially very wrong with their multi-threading (Control-derived classes are not thread-safe)

Accessing win forms control throws exception from different thread only in Visual Studio

I got answer once I decided to post question here :)

https://msdn.microsoft.com/en-us/library/ms171728.aspx

This exception occurs reliably during debugging and, under some circumstances, at run time.

So my use case is not in the:
"under some circumstances, at run time"

I hope this helps someone who gets the same issue.

TPL issue when DEBUG mode, in Release mode all is okay

Checkout Hans Passant's answer on this question, Why is cross thread operation exception not thrown while running exe in bin\Debug he is saying cross-thread error checking is only enabled when a debugger is attached, also you can disable cross-thread errors check manually

Control.CheckForIllegalCrossThreadCalls = false;

Why are we allowed to modify the form title from a thread pool thread?

Cross-thread checks are disabled by default in winforms unless the debugger is attached. This can be seen in the initialization of the checkForIllegalCrossThreadCalls field:

private static bool checkForIllegalCrossThreadCalls = Debugger.IsAttached;

If I had to guess, I'd say this is an attempt to preserve retro-compatibility. .NET 1.1 did not have cross-thread checks (and back in the days I was left wondering why my apps would mysteriously crash after a few hours), they were added with .NET 2.0. But this is a huge breaking change, and I suppose that's why they made it opt-in. With WPF, cross-thread checks were introduced right-away, so they could activate them for everybody.

In light of this, I strongly recommend to enable cross-thread checks manually in any winform project by adding this line to the entry-point:

[STAThread]
static void Main()
{
Control.CheckForIllegalCrossThreadCalls = true;

Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}


Related Topics



Leave a reply



Submit