Background processing on UI thread? (Winforms) - winforms

Is there a (or, do you have your own) preferred way to do background processing in slices on the UI thread in Windows Forms? Like OnIdle() in MFC?
In native Windows programming you could roll your own message loop to do this, but Application.Run() doesn't give us access to the message loop.
The Application.Idle event gives us no way to trigger it repeatedly.
I guess you could call native PostMessage() with P/Invoke (since there's no managed version) to post yourself a private "WM_IDLE" message, and override WndProc() to catch it. I don't know how this would get along with Application.Run().
So far I've used a short Timer for this, but I'm afraid I may be losing cycles sleeping, especially since the actual Timer resolution is coarser than the nominal 1 ms minimum.

The best option I've seen is to use a modified version of the Managed DirectX Render Loop designed by Tom Miller. By adding a call to Thread.Sleep() inside the render loop, you can pull your CPU usage down dramatically.
This does require a P/Invoke call to track that the application is still idle, but as long as it's idle, you can make a "timer" that fires continuously during the idle phases, and use that to do your processing.
That being said, on modern systems, you almost always have extra cores. I would suggest just doing the processing on a true background thread.

I thought of my own possible answer, inspired by Reed's talk of multithreading. I may have a way to retrigger Application.Idle:
Create a hidden form, let's call it formRetrigger.
In Application.Idle, launch my Retrigger() method on a thread pool thread.
Retrigger() calls formRetrigger.InvokeOnClick() (or any of the other "Control.Invoke" methods). I expect this to launch another message through Application's queue, causing Idle to get triggered again.

Related

INotifyPropertyChanged UI Hang

I have an WPF application which contains many classes that support INotifyProprtyChange interface. The property on this classes are changed at high rate from different threads and the problem is that in some cases application UI thread hangs , along with the UI thread other threads that have code calling PropertyChange also hangs while trying update properties.
I did a deadlock check with Windbg but it could detect none.
Now i looked at the stack trace of the threads holding locks and what i always see is that at least one same or different thread has
00000000002d0ab8 000000007712908a [HelperMethodFrame_1OBJ: 00000000002d0ab8] System.Threading.SynchronizationContext.WaitHelper(IntPtr[], Boolean, Int32)
00000000002d13b0 000000007712908a [GCFrame: 00000000002d13b0]
00000000002d16c8 000000007712908a [HelperMethodFrame_1OBJ: 00000000002d16c8] System.Threading.ReaderWriterLock.AcquireReaderLockInternal(Int32)
00000000002d17f0 000007fef1bcf1a0 MS.Internal.ReaderWriterLockWrapper.get_ReadLock()
00000000002d1830 000007fef1ba8d44 System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(System.Object, System.ComponentModel.PropertyChangedEventArgs)
and another
000000001f64d138 000000007738186a [HelperMethodFrame_1OBJ: 000000001f64d138] System.Threading.ReaderWriterLock.AcquireReaderLockInternal(Int32)
000000001f64d260 000007fef1bcf1a0 MS.Internal.ReaderWriterLockWrapper.get_ReadLock()
000000001f64d2a0 000007fef1ba8d44 System.ComponentModel.PropertyChangedEventManager.OnPropertyChanged(System.Object, System.ComponentModel.PropertyChangedEventArgs)
So its looks like PropertyChangedEventManager wait for some thread to complete while other threads wait to acquire lock?
Now i am having troubles figuring out why this occurs as its sporadic and usually happens when there is many property change events. From what i see other threads in application that not calling property change continue to run normally.
As far as I know PropertyNotifyChanged is only supported in the UI thread.
Just guessing. In bigger environments one problem happends quiet easy: 2 properties update each other endlessly. The setter of prop A calls the setter of prop B which in turn calls the setter of A again. Usually of course not that obvious as described but could be worth to look at.

clutter timeline not emitting signals in time

the timeline functionality in moblin clutter is used to do a callback every given milliseconds.although it is emitting signals lot faster(every 1ms or so). Why does this happen?
ClutterTimeline * clutter_timeline_new(guint msecs);
you should not be using a Timeline to get a notification (and execute code) that N amount of milliseconds have elapsed. ClutterTimeline is a object that is tied to the redraw cycle of the UI. timelines are advanced every time Clutter redraws a frame, to let the application code know that it has to update its state.
if you just need to have your code called after an interval, use g_timeout_add() instead; this function is tied only to the main loop, and not to the redraw cycle. there are other considerations to be taken care of when using a timeout, so you should read the documentation:
http://developer.gnome.org/glib/stable/glib-The-Main-Event-Loop.html#g-timeout-add
strictly speaking, if you're using Moblin, you're probably using a very old version of Clutter, so there may be bugs as well; not that I know of bugs where the ClutterTimeline::new-frame signal is called every millisecond, mind you.

WPF Application thread usage going up and up

I have a multithreaded WPF application that is using > 600 threads after is has been running for more than 8 hours. All but approximately 10 of these threads have a stack trace that is very similar to this:
Stack trace 1:
ntkrnlpa.exe!NtInitialUserProcessBuffer+0x7b
ntkrnlpa.exe!MiAddWorkingSetPage+0x174
ntkrnlpa.exe!MiAddWsleHash+0x12a
ntkrnlpa.exe!PopSystemButtonHandler+0x141
ntkrnlpa.exe!KiInterruptTemplate+0x62
ntdll.dll!KiFastSystemCallRet
ntdll.dll!ZwWaitForMultipleObjects+0xc
KERNEL32.dll!WaitForMultipleObjectsEx+0x12c
mscorwks.dll!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f
mscorwks.dll!Thread::DoAppropriateAptStateWait+0x3c
mscorwks.dll!Thread::DoAppropriateWaitWorker+0x13c
mscorwks.dll!Thread::DoAppropriateWait+0x40
mscorwks.dll!WaitHandleNative::CorWaitOneNative+0x156
mscorlib.ni.dll+0x1f68af
mscorlib.ni.dll+0x1caa17
WindowsBase.ni.dll+0x24ac34
WindowsBase.ni.dll+0x2aeb1e
WindowsBase.ni.dll+0x9445d
WindowsBase.ni.dll+0x9267f
mscorwks.dll!JITutil_IsInstanceOfAny+0x106
mscorlib.ni.dll+0x1e842f
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!MethodDesc::CallDescr+0x19c
mscorwks.dll!MethodDesc::CallTargetWorker+0x1f
mscorwks.dll!MethodDescCallSite::Call+0x1a
mscorwks.dll!ExecuteCodeWithGuaranteedCleanupHelper+0x9f
mscorwks.dll!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0x10f
mscorlib.ni.dll+0x235677
mscorlib.ni.dll+0x2202a5
mscorlib.ni.dll+0x1e839b
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!DispatchCallBody+0x1e
mscorwks.dll!DispatchCallDebuggerWrapper+0x3d
mscorwks.dll!DispatchCallNoEH+0x51
mscorwks.dll!AddTimerCallback_Worker+0x66
mscorwks.dll!Thread::DoADCallBack+0x32a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0xe3
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x30a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x33e
mscorwks.dll!ManagedThreadBase::ThreadPool+0x13
mscorwks.dll!AddTimerCallbackEx+0x83
mscorwks.dll!AddTimerCallback+0x10
mscorwks.dll!ThreadpoolMgr::AsyncTimerCallbackCompletion+0x64
mscorwks.dll!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x9a
mscorwks.dll!ThreadpoolMgr::ExecuteWorkRequest+0xaf
mscorwks.dll!ThreadpoolMgr::WorkerThreadStart+0x20b
mscorwks.dll!Thread::intermediateThreadProc+0x49
KERNEL32.dll!BaseThreadStart+0x37
Stack Trace 2:
ntkrnlpa.exe!NtInitialUserProcessBuffer+0x7b
ntkrnlpa.exe!MiAddWorkingSetPage+0x174
ntkrnlpa.exe!MiAddWsleHash+0x12a
ntkrnlpa.exe!PopSystemButtonHandler+0x141
ntkrnlpa.exe!KiInterruptTemplate+0x62
ntdll.dll!KiFastSystemCallRet
ntdll.dll!ZwWaitForMultipleObjects+0xc
KERNEL32.dll!WaitForMultipleObjectsEx+0x12c
mscorwks.dll!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f
mscorwks.dll!Thread::DoAppropriateAptStateWait+0x3c
mscorwks.dll!Thread::DoAppropriateWaitWorker+0x13c
mscorwks.dll!Thread::DoAppropriateWait+0x40
mscorwks.dll!WaitHandleNative::CorWaitOneNative+0x156
mscorlib.ni.dll+0x1f68af
mscorlib.ni.dll+0x1caa17
WindowsBase.ni.dll+0x24ac34
WindowsBase.ni.dll+0x2aeb1e
WindowsBase.ni.dll+0x9445d
WindowsBase.ni.dll+0x9267f
mscorwks.dll!JITutil_IsInstanceOfAny+0x106
mscorlib.ni.dll+0x1e842f
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!MethodDesc::CallDescr+0x19c
mscorwks.dll!MethodDesc::CallTargetWorker+0x1f
mscorwks.dll!MethodDescCallSite::Call+0x1a
mscorwks.dll!ExecuteCodeWithGuaranteedCleanupHelper+0x9f
mscorwks.dll!ReflectionInvocation::ExecuteCodeWithGuaranteedCleanup+0x10f
mscorlib.ni.dll+0x235677
mscorlib.ni.dll+0x2202a5
mscorlib.ni.dll+0x1e839b
mscorwks.dll!CallDescrWorker+0x33
mscorwks.dll!CallDescrWorkerWithHandler+0xa3
mscorwks.dll!DispatchCallBody+0x1e
mscorwks.dll!DispatchCallDebuggerWrapper+0x3d
mscorwks.dll!DispatchCallNoEH+0x51
mscorwks.dll!AddTimerCallback_Worker+0x66
mscorwks.dll!Thread::DoADCallBack+0x32a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0xe3
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x30a
mscorwks.dll!Thread::ShouldChangeAbortToUnload+0x33e
mscorwks.dll!ManagedThreadBase::ThreadPool+0x13
mscorwks.dll!AddTimerCallbackEx+0x83
mscorwks.dll!AddTimerCallback+0x10
mscorwks.dll!ThreadpoolMgr::AsyncTimerCallbackCompletion+0x64
mscorwks.dll!UnManagedPerAppDomainTPCount::DispatchWorkItem+0x9a
mscorwks.dll!ThreadpoolMgr::ExecuteWorkRequest+0xaf
mscorwks.dll!ThreadpoolMgr::WorkerThreadStart+0x20b
mscorwks.dll!Thread::intermediateThreadProc+0x49
KERNEL32.dll!BaseThreadStart+0x37
Application uses System.Threading.Timer to periodically poll for data from several webservices using a WCF client proxy and at any giving time, could be making about 20 of these requests at the same time. Each call to a webservice instantiates a new proxy instance but the client is always closed when a response is received from the webservice.
Application also manipulates with bitmaps for a GIS and this is also done on a periodic interval. No where in code am I explicitly creating threads besides localized usage of the Timer class to poll for data periodically. The GIS does
use the BackgroundWorker but they do limit the thread count.
Anyone have an idea on what is spawning these new threads and why they are not being disposed?
TIA.
Yeah, looks like something you shouldn't ignore. They are the threadpool thread that the Timer class uses to make the callback. They are deadlocked, looks like they are waiting for a method call that's marshaled by COM to complete. There should be another thread in your program, one of the other 10 on which you created the GIS object. That thread is not pumping a message loop, a hard requirement for an STA thread that creates single apartment threaded COM components. Or it is stuck itself, not re-entering the message loop. Getting a managed stack trace ought to make it easier to see where the thread is stuck.
Trying to use threads on a COM object that explicitly doesn't support them (very few do) is pointless. Be sure to create the GIS object on your program's main UI thread. And use a DispatcherTimer. Creating your own STA thread that pumps a message loop can be a solution when the GIS component is taking too much of a hit on your user interface.
Problem was not GIS related but was due to System.Threading.Timer call backs queuing up as they were being called faster than they could be actioned. Problem was further compounded by the fact that timer call back was doing a Dispatcher.Invoke to the main user interface thread to refresh data grids. Dispatcher.Invoke was blocking when main user interface was busy, say when user was panning and zooming on map, and before timer call back got a chance to complete it was invoked again.
Fixed problem by temporarily stopping timer when it starts executing the call back and restarting it again after call back is complete. Also, instead of doing a Dispatcher.Invoke to get my grids updated, I changed it to a Dispatcher.BeginInvoke to avoid blocking.

Should I run everything in a background thread?

I am designing an application which has the potential to hang while waiting for data from servers (either Database or internet) the problem is that I don't know how best to cope with the multitude of different places things may take time.
I am happy to display a 'loading' dialog to the user while access is happening but ideally I don't want this to flick up and disappear for short running operations.
Microsoft word appears to handle this quite nicely, as if you click a button and the operation takes a long time, after a few seconds you get a 'working..' dialog. The operation is still synchronous and you can't interrupt the operation. However if the same operation happens quickly you obviously don't get the dialog.
I am happy(ish) to devise some generic background worker thread handler and 99% of my data processing is already done in static atomic methods, but I would like to go best practice on this one if I can.
If anyone has patterns, code or suggestions I welcome them all
Cheers
I would definitely think asynchronously using a pattern with 2 events. The first "event" is that you actually got your data from wherever/whenever you had to wait for it. The second event is a delay timer. If you get your data before this timer pops, all is well and good. If not, THEN you pop up your "I'm busy" and allow them to cancel the request. Usually cancel just mean "ignore" when you finally get the response.
Microsoft word appears to handle this quite nicely, as if you click a button and the operation takes a long time, after a few seconds you get a 'working..' dialog. The operation is still synchronous and you can't interrupt the operation. However if the same operation happens quickly you obviously don't get the dialog.
If this is the behavior your want...
You could handle this, fairly easily, by wrapping a class around BackgroundWorker. Just time the start of the DoWork event, and the time to the first progress report. If a certain amount of time passes, you could show your dialog - otherwise, block (since it's a short process).
That being said, any time you're doing work that can be processed asynchronously, I'd recommend doing it that way. It's much nicer to never block your UI for a noticable interval, even if it's short. This becomes much simpler in .NET 4 (or 3.5 with Rx framework) by using the task parallel library.
Ideally you should be running any IO or non-UI processing either in a background thread or asynchronously to avoid locking up the UI.

In WinForms, why can't you update UI controls from other threads?

I'm sure there is a good (or at least decent) reason for this. What is it?
I think this is a brilliant question -
and I think there is need of a better
answer.
Surely the only reason is that there
is something in a framework somewhere
that isn't very thread-safe.
That "something" is almost every single instance member on every single control in System.Windows.Forms.
The MSDN documentation for many controls in System.Windows.Forms, if not all of them, say "Any public static (Shared in Visual Basic) members of this type are thread safe. Any instance members are not guaranteed to be thread safe."
This means that instance members such as TextBox.Text {get; set;} are not reentrant.
Making each of those instance members thread safe could introduce a lot of overhead that most applications do not need. Instead the designers of the .Net framework decided, and I think correctly, that the burden of synchronizing access to forms controls from multiple threads should be put on the programmer.
[Edit]
Although this question only asks "why" here is a link to an article that explains "how":
How to: Make Thread-Safe Calls to Windows Forms Controls on MSDN
http://msdn.microsoft.com/en-us/library/ms171728.aspx
Because you can easily end up with a deadlock (among other issues).
For exmaple, your secondary thread could be trying to update the UI control, but the UI control will be waiting for a resource locked by the secondary thread to be released, so both threads end up waiting for each other to finish. As others have commented this situation is not unique to UI code, but is particularly common.
In other languages such as C++ you are free to try and do this (without an exception being thrown as in WinForms), but your application may freeze and stop responding should a deadlock occur.
Incidentally, you can easily tell the UI thread that you want to update a control, just create a delegate, then call the (asynchronous) BeginInvoke method on that control passing it your delegate. E.g.
myControl.BeginInvoke(myControl.UpdateFunction);
This is the equivalent to doing a C++/MFC PostMessage from a worker thread
Although it sounds reasonable Johns answer isn't correct. In fact even when using Invoke you're still not safe not running into dead-lock situations. When dealing with events fired on a background thread using Invoke might even lead to this problem.
The real reason has more to do with race conditions and lays back in ancient Win32 times. I can't explain the details here, the keywords are message pumps, WM_PAINT events and the subtle differences between "SEND" and "POST".
Further information can be found here here and here.
Back in 1.0/1.1 no exception was thrown during debugging, what you got instead was an intermittent run-time hanging scenario. Nice! :)
Therefore with 2.0 they made this scenario throw an exception and quite rightly so.
The actual reason for this is probably (as Adam Haile states) some kind of concurrency/locky issue.
Note that the normal .NET api (such as TextBox.Text = "Hello";) wraps SEND commands (that require immediate action) which can create issues if performed on separate thread from the one that actions the update. Using Invoke/BeginInvoke uses a POST instead which queues the action.
More information on SEND and POST here.
It is so that you don't have two things trying to update the control at the same time. (This could happen if the CPU switches to the other thread in the middle of a write/read)
Same reason you need to use mutexes (or some other synchronization) when accessing shared variables between multiple threads.
Edit:
In other languages such as C++ you are
free to try and do this (without an
exception being thrown as in
WinForms), but you'll end up learning
the hard way!
Ahh yes...I switch between C/C++ and C# and therefore was a little more generic then I should've been, sorry... He is correct, you can do this in C/C++, but it will come back to bite you!
There would also be the need to implement synchronization within update functions that are sensitive to being called simultaneously. Doing this for UI elements would be costly at both application and OS levels, and completely redundant for the vast majority of code.
Some APIs provide a way to change the current thread ownership of a system so you can temporarily (or permanently) update systems from other threads without needing to resort to inter-thread communication.
Hmm I'm not pretty sure but I think that when we have a progress controls like waiting bars, progress bars we can update their values from another thread and everything works great without any glitches.

Resources