I have an application which uses WPF for its GUI but, on command kicks off a very heavy processing load.
I noticed that my GUI was rather sluggish when the engine (heavy processing) was running and when using the 'Application Timeline' tool in VS2015, I noticed that some of my engine code was being run on the UI thread.
The engine is started with the following line which, if i understand the LongRunningflag, creates a new thread and runs the given function on that thread.
rootTask = Task.Factory.StartNew(DoWork, TaskCreationOptions.LongRunning);
The DoWork method referenced above repeatedly uses Parallel.For to queue up hundreds of tasks.
Is it possible that the dispatcher thread is 'helping-out' by running tasks from the TaskScheduler queue? If so, is it possible to prevent this to keep the GUI responsive (allbeit to the detriment of the background tasks)?
Is it possible that the dispatcher thread is 'helping-out' by running tasks from the TaskScheduler queue?
No, as far as I know, that's not possible. If some code that comes from the Task really executes on the dispatcher thread, then that means the task had to explicity schedule it there.
Related
Is it possible to make a synchronous network call on UI thread in WPF (Windows Phone 8).
(I know it's cons, but still i need this functionality to make it work with some ported code)
Tried using autoresetevent method. Due to deadlock, it is blocking ui thread and app hangs forever.
Even tried with webclient. still the UI thread is getting blocked and app hangs forever.
Any help...
This is a very bad idea - I've found that doing this by accident will actually lead to a complete deadlock of your UI. You need to use an asynchronous method.
Callbacks from asynchronous network operations are queued on the UI thread. If you block the thread to wait for it, the callback will never arrive because it is waiting for access to the same thread.
You do have another option though... If you have ported the code, then you will have to change it to support async operations.
I have a very complex WPF application where the pages that I display and processed are in dlls. This works fine so far.
I set up a timer in the main page of the app that looks for communication coming in from an external source. When I get a communication (and I am being vague to not not add confusion) I parse it and if the message is "xyx" I need to start the XYL dll's UI. I get the calling thread must be sta bacause many ui components require this.
I see the write ups on the web about having to call the Invoke() and that I can't use a worker thread but rather a background thread.
Is my problem the System.Timers.Timer that I am using? Is that causing a worker thread? I am not sure where in my calls I need to start a thread to run this (or how to handle it).
Any suggestions?
System.Timers.Timer runs on a worker thread and cannot access UI elements. See here and here for more information on that.
It's ok to use that kind of timer, you just need to get back to the UI (dispatcher) thread before you touch the UI pieces. You can do this by calling Dispatcher.Invoke or Dispatcher.BeginInvoke and passing in the delegate you want to run. That'll get the new UI pieces onto your original UI thread. If you want them to run on their own UI thread (perhaps in a different window) then you need to set that up yourself.
Timers normally run on a threadpool thread which are MTA.
Use a DispatcherTimer instead or use Dispatcher.Invoke. The dll's UI will then run on the same thread as main page's UI (which is STA)
If you want the dll's UI to run on a different thread you need to create the thread yourself and set it to STA.
The full error I get is as follows:
The CLR has been unable to transition from COM context 0x1a8188 to COM context 0x1a8018 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.
Any idea what this means? And how is should be solved? I tried searching on Google, but couldn't find anything of consequence, i.e. relating to my specific scenario.
Edit:
The Specific scenario:
1. Integrating WPF into WinForms
2. The WPF screens are written for a plugin dll, which is dynamically loaded into the main application.
Thanks
Hasanain
This means that you created an object on thread A, then tried to use it on thread B, but thread A was really busy and the COM object requires that it be running on thread A. Try to see why thread A is busy.
I have some code in my project that reads from and writes into Excel 2003 using Excel COM API. Now this piece of code is called from two places:
1. From within the Excel add-in itself, on the same thread.
2. From a WPF application, where the WPF window was invoked on a separate thread.
The issue is, when the WPF application invokes the code, the normal operation of reading from Excel that should take 10 seconds is taking 2 minutes. I think it is because of the invocation from a new thread, but I'm not 100% sure.
Any ideas?
You have a number of things to consider:
The COM API likely launches the Excel process. It takes time to start the process and wait for it to be ready.
There is likely a process boundary being crossed, this is slower than in-proc stuff.
You may have fallen into the trap of thread-affinity of the COM objects you create in code. They might have affinity with the thread they were created on, meaning even though you use a COM object on another thread, the actual running of that code is marshalled back to the owning thread of the object. This should be obvious, however, as your UI will stutter if the code is intensive enough.
Sorry this isn't a direct answer, but it gives some points to explore.
How does the Dispatcher thread work in wpf a UI control?
Edit.
If you have a long running task, delegate it to a background thread using a BackGroundWorker, and then you won't need to use the dispatcher to pass messages back to the UI. This is a very good article.
Its a very broad question. I suggest you start here with WPF Architecture.
Most objects in WPF derive from
DispatcherObject, which provides the
basic constructs for dealing with
concurrency and threading. WPF is
based on a messaging system
implemented by the dispatcher. This
works much like the familiar Win32
message pump; in fact, the WPF
dispatcher uses User32 messages for
performing cross thread calls.
There are really two core concepts to
understand when discussing concurrency
in WPF – the dispatcher and thread
affinity.
During the design phase of WPF, the
goal was to move to a single thread of
execution, but a non-thread
"affinitized" model. Thread affinity
happens when a component uses the
identity of the executing thread to
store some type of state. The most
common form of this is to use the
thread local store (TLS) to store
state. Thread affinity requires that
each logical thread of execution be
owned by only one physical thread in
the operating system, which can become
memory intensive. In the end, WPF’s
threading model was kept in sync with
the existing User32 threading model of
single threaded execution with thread
affinity. The primary reason for this
was interoperability – systems like
OLE 2.0, the clipboard, and Internet
Explorer all require single thread
affinity (STA) execution.
Given that you have objects with STA
threading, you need a way to
communicate between threads, and
validate that you are on the correct
thread. Herein lies the role of the
dispatcher. The dispatcher is a basic
message dispatching system, with
multiple prioritized queues. Examples
of messages include raw input
notifications (mouse moved), framework
functions (layout), or user commands
(execute this method). By deriving
from DispatcherObject, you create a
CLR object that has STA behavior, and
will be given a pointer to a
dispatcher at creation time.