Get the owner of thread that is executing - c#

when I run the project I receive the famous "Calling thread cannot access..." exception. Now, first I would like to see why is this happening, since my code should not be creating this new thread at this stage, so I would like to know who created this thread.
When exception occurs, StackTrace reports that the method was called from external code (only two items in StackTrace).
Threads window reports its Priority only (no explanation in Name).
How can I get more information about the current thread running? Like which library created it? Is it external code or mine?

Thread.CurrentThread should tell you all what you need to know about a managed thread. If "Threads window" doesn't shows name means, there is no name specified.
Also there is no way you could find which library created the thread. No such information stored anywhere.

Related

Cannot change a property of WPF from a websocket event

I am trying to change a property of WPF from a websocket event however I am encountering a problem where I get this exception: https://i.imgur.com/lsFt3OR.png
I googled the exception and it brought up this Microsoft article: https://learn.microsoft.com/en-us/dotnet/api/system.invalidoperationexception?view=netcore-3.1
They said that I could use Dispatcher.Invoke to remove the exception (as seen in the screenshot). I did that on a render thread but I still get the error.
enter image description here
Secondly I tried to invoke the function the dispatch the thread onto the main thread which resulted into the error in the attempted solution. Strangely enough I had access to change the property according to the print debugging I did.
enter image description here
I know this is an old thread but I have run into this same issue in my searching and if this is more clearly answered others may find it helpful. That said what Andrej Dobes is correct this may just provide more clarity.
Based off of your response to the previous answer it looks as though you were still confused. The code would need to look similar to this on line 49 of your previous screenshot:
PlayerDataSocket.OnMessage += Application.Current?.Dispatcher?.Invoke(PlayerDataSocket_OnMessage)
The ? are added as not null checks and aren't necessary for your situation most likely.
You need to use the dispatcher of the thread that created the object originally which I guess would be the UI thread since you're setting the image. When invoking dispatcher from static class directly you always get the one that is actually assigned to the actual thread, which means you would have to have the reference to a dispatcher of the thread that owns the object.
DispatcherPriority.Render does not say that you want to exeucute it on a render thread but it's setting the priority when it should be executed, you check more at msdn about that.
To access the UI thread dispatcher you can use the code below, but then the UI thread actually needs to be the owner of the object you're setting
Application.Current.Dispatcher.Invoke(action);

How does Deployment.Current.Dispatcher.BeginInvoke(()=>{}) work?

Whenever I get a Invalid-CrossThread-Access error in my windows phone project, I execute my code inside Deployment.Current.Dispatcher.BeginInvoke(() => {}) and everything works fine after that. However I never clearly understood the meaning of it.
Can someone put some light on it giving detailed explanation on how does it resolves my cross thread errors and what each of its parts mean. As far as I have googled for it, it is used to execute some code on UI thread.
But what are deployment, current, and dispatcher objects. How else can I use them.
TIA
The problem lies in the design of the Windows platform. You can't change the user interface (specifically Win32 objects) from another thread then the objects are created from.
Dispatcher.BeginInvoke executes the delegate provided as parameter on the UI thread, not on the thread it is called from.
Deployment.Current is a singleton reference to the current running application, the Dispatcher is the part of the program that is responsible for passing messages around. BeginInvoke the method that does actually finds the right thread and executes the delegate.
The difference between BeginInvoke and Invoke it that the first is ran asynchronously. Invoke is executed immediately and execution is suspended until the method finishes.

Multi-thread debugging with VisualStudio and WebBrowser Windows.Forms controls

We're creating a few threads in a Windows.Forms solution.
We've also got a BrowserControl (yup, it's OAUTH) and of course I'm finding issues with debugging -
Cross-thread operation not valid: Control 'xxForm' accessed from a
thread other than the thread it was created on
And yet I am calling 'correctly'
xxForm.Show()
by ensuring it's wrapped in an invoke call
.Invoke(new MethodInvoker())
and still I get the thread issue. I can do everything else (Focus, BringToFront) it's the Show that errors.
Moreover, the GUI never gets the browser response and shows. In the VS debugger I get the above threading erropr (apartment state of background thread == MTA). When run as an EXE the same code has a threading aparement of STA and the GUI will never show when debugging, but if I run the EXE directly, there's no threading issue, the browser control just never responds to input.
Spo the questions are:
Why the different behjaviour in VS / EXE?
How do I debug in VS?
Does the BrowserControl play ok with multiple threads?
Update
YES I KNOW there's no code - it's too long. I'll see what I can do.
Also please read the question before posting an answer. I am invoking the background thread on the UI thread. That's not the issue. This has NO EFFECT on the result. I'll down vote answers that recommend that.
Also some hope - I've searched for many hours. It's linked the the message pump. Unless the message pump is running the DocumentCompleted event isn't received.
Update 2
Best I manage is pseudo code:
Program:
startWorkQueue
LoadForm (don't show)
Thread1:
addToQueue
Thread2:
readFromQueue
ShowForm (on occasion)
Now the ShowForm method is on a Windows.Form control.
Within this any call is made via an Invoke, so that despite the 2nd thread making the call the ShowForm, the actual .Show() etc etc calls are on the UI thread.
So what am I missing? I just don't understand why there's a cross thread exception....
Ok I've found out what was going on and I'll post here for reference.
I hope it helps someone in the future.
We had some different constraint to the vanilla Forms applications - our Forms were created on the Main thread but had Show() called on a different thread. We also don't have a starting UI - we sit in the background and sometimes react to events with UI prompts.
As such a number of issues hit us. Rather than list them all I'll detail our takeaways:
Application.Run
If decide NOT to Show a Form at the start of your application… then you'll need to consider threads carefully (see Form.Show notes)
Form.Show
This does all resource allocation etc, NOT the Load/ctor
Performs handle creation / resource allocation
Handle creation
Hwnd
If we attempt to access certain Form properties before it has Show(n) then you'll need to create a handle manually (or an Exception is created)
• As easy as if (!IsHandleCreated) { CreateHandle(); }
HOWEVER
This create the control/form
Therefore the control/form is created on the Thread that calls the Handle create
This must be the same UI thread (STA) as the Main function
• Otherwise much weirdness occurs
SO
You aren't restricted by what to do with Application.Run
You can access properties in .Show (but you may need to create a handle first)
You can call Show from a different thread, but ensure the handle is ONLY created on the main thread
I hope it helps, I can provide more details on our specific problems if need be.
Various aids that helped included displaying ManagedThread AND ProcessId in the log and scouring MSDN.
Since the code has not been pasted, I would like to remind you that in WinForms, the UI elements should be accessed only on the UI thread. Any other thread apart from UI thread should not be updating the UI elements directly.

Terminate a Thread running code I can't control

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.

How do I suspend all threads after my program crashes?

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.

Categories