I have a BackgroundWorker that monitors a folder for files in 1sec interval. If it finds file(s) then it raises the ReportProgress(0, fileName) for every found file.
On the main thread I subscribe to that event and handle each file.
This is: one found file = one raised event = one handled file
My question is about queuing events if the main thread is slow.
For example the 'file watcher' can find and raise 1000 events per second but on the main thread handling each file takes 1 sec. So events are queued.
Is there any limit for that kind of queuing in .NET ?
Thanks,
Bartek
No the main thread will eventually process all the files. However, if you have some sort of GUI I would recommend you do the processing on a separate thread.
BackgroundWorker internally uses SynchronizationContext to Post asynchronous messages. If it was GUI thread starting the BW, it'd use a specialized WinForms SynchronizationContext and report progress to that main thread using message loop.
In your case, it's a windows service thread and as such has no SynchronizationContext. What happens is the default SynchronizationContext is instantiated and used. The behavior is then completely different and a new ThreadPool is used for asynchronous messages. As a result, your file processing will take place in separate threads started by that internal ThreadPool, as opposed to main thread as it is in WinForms.
While ThreadPool should correctly handle large queues (could not immediately find any hard limits on ThreadPool queue size - anyone know?), do know that you can not assume deterministic sequential file processing in this pattern.
Related
I am having an issue where I have a Windows CE compact framework Application written in C#, where I have the primary GUI thread set to normal priority and a communication thread set to above normal priority to get as close to pseudo real time performance. The issue I am having is within a button handler I run a loop to load config data from a file to the GUI before allowing it to be edited. This takes around 2-3 seconds to complete. While this blocking in the event handler is happening, my higher priority communication thread is being blocked. There are no locks are thread syncs in place. The communicatio thread has no dependencies on the GUI thread.
This is how I spawn my comm thread:
MbWorkerThread = new Thread(MbPollingThread);
MbWorkerThread.IsBackground = true;
MbWorkerThread.Priority = ThreadPriority.AboveNormal;
MbWorkerThread.Start();
It is an MTA application. Also, I have tried to use Thread.Sleep(1) in the GUI event handler to yield to the higher priority thread and it does not work. I also tried using signals to yield to the higher priority thread, and that does not work. The only thing that works is if I place Application.DoEvents() in the loop while loading config in the event handler. This of coarse whas just a test, as I do not want to sprinkle Application.DoEvents() throught my code to make it work since I know Application.DoEvents() is dangerous.
My understanding is that the primary GUI thread is a foreground thread, but a thread none the less. Also, I have made the communication thread a background thread just to allow it to be killed when the primary thread is exited.
I have tried everything, I have search the Internet endlessly before asking this question.
Any help will be greatly appreciated.
P.S. - I though about a form timer but I know it runs in the GUI thread so that would not help. I though about another thread but I really did not what to marshall GUI updates via Invoke.
Your program starts in Main(), where you typically call Application.Run( new MyForm() ). Application.Run() implements the standard Windows Message Pump, which deals with messages from the OS and other applications, including user input, inter-process communication, repaint requests, etc.
GUI events, like Button click, are dispatched via this thread. If you perform long-running work in an event handler, other messages are not being processed.
Application.DoEvents() blocks the calling thread, and waits for all pending messages to be processed. If DoEvents helps your communication thread when Sleep(1) did not, then I suspect there is a dependency between your communication thread and the GUI/Message Pump thread.
Even if this is not the case, it is not a good idea to block the GUI thread. Move your file loading into the background with ThreadPool.QueueUserWorkItem() and marshal the results back to the UI at the end with Invoke or BeginInvoke.
BeginInvoke instead of Invoke fixed the issue. Thanks for the replies.
I'm working on a program which reacts to events coming from an internet socket, and possibly from timers as well. It seems natural to use two threads:
One for the main program
A second one which listens to the socket, parses the input, and raises an appropriate event.
Additional requirements:
The application should not rely on a UI thread (it may be run as a console application).
The main program should process messages synchronously, i.e. in the order in which they arrived.
The main thread must not block on waiting for timers (I guess this means I have to run timers on different threads).
And now for some questions :-):
I'm guessing requirement #1 means that I don't have a built-in message pump, so I can't use Invoke() from the socket listener / timer threads. Is this correct?
How can I safely raise events on one thread (e.g. the listener), and have the subscribers run synchronously on another (the main thread)?
It is very likely that new events will be raised before the subsequent handler is done. What will happen in this case? Will the event be buffed somewhere by the CLR, or will it be ignored?
And last but not least: I guess I'm aiming for the parallel for the message Producer/Consumer paradigm, but instead of messages, I want to use events. Do you think there is a better approach?
Thanks,
Boaz
EDIT
I want to explain my motivation for using events in the first place. The application is an automated trading engine which has to respond to events that happen in the market (e.g. a change in the price of a stock). When this happens, there may be multiple subscribers on the main thread which should be invoked, which is a classical scenario to use events.
I guess I can always use the Producer/Consumer with some message queue, and have the consumer raise events on the main thread, but I figured there might be a more direct way.
I think using messages will be the simplest way. If you are using C# 4 this is very easy thanks to the BlockingCollection<>
So have a shared BlockingCollection, where Message is your message class.
Then in your worker thread you do this
var msgEnum = blockingCollection.GetConsumingEnumerable();
//Per thread
foreach( Message message in msgEnum )
{
//Process messages here
}
That is it.
The GetConsumingEnumerable() will block until there is a message to process. It will then remove the message from the queue and your loop will process it.
What is nice about this is that you can add more threads and in each one you just have the foreach loop.
When you are done call blockingCollection.CompletedAdding();
BTW the queue handles concurrency and will queue messages sent at the same time etc.
Hope this helps
Andre
You could implement a shared queue between your threads. Whenever an event is raised you could push it in the queue. The main thread is an endless loop that checks for new events, removes them from the queue, handles the event and when there are no more events it sleeps for some time.
I have a Form that uses a BackgroundWorker to execute a series of tests. I use the ProgressChanged event to send messages to the main thread, which then does all of the updates on the UI. I've combed through my code to make sure I'm not doing anything to the UI in the background worker. There are no while loops in my code and the BackgroundWorker has a finite execution time (measured in seconds or minutes). However, for some reason when I lock my computer, often times the application will be hung when I log back in. The thing is, the BackgroundWorker isn't even running when this happens. The reason I believe it is related to the BackgroundWorker though is because the form only hangs when the BackgroundWorker has been executed since the application was loaded (it only runs when given a certain user input).
I pass this thread a List of TreeNodes from a TreeView in my UI through the RunWorkerAsync method, but I only read those nodes in the worker thread..any modifications I make to them is done in the UI thread through the progressChanged event.
I do use Thread.Sleep in my worker thread to execute tests at timed intervals (which involves sending messages over a TCP socket, which was not created in the worker thread).
I am completely perplexed as to why my application might be hanging. I'm sure I'm doing something 'illegal' somewhere, I just don't know what.
I pass this thread a List of TreeNodes from a TreeView in my UI through the RunWorkerAsync method, but I only read those nodes in the worker thread.
By "only read" I assume you mean "only access property getters". But property getters can execute code that you don't control - for example TreeNode.IsSelected will call a native method and send a Windows message (take a look with Reflector).
Instead you should extract the data you need from the TreeView in the UI thread and pass it to the background worker. Not only will you avoid this problem, but your design will be more loosely coupled.
Well, this one is old but it turned out that the problem was completely unrelated to my code. Due to recent changes in our software, the amount of logging had increased exponentially and our log buffer was overflowing causes the application to crash. It was just a coincidence that this was happening at the same time that I was working on this specific piece of code. In any case, I still made sure that I wasn't doing any operations on UI elements from a BackgroundWorker, even if it was as trivial as checking/unchecking a TreeNode.
Sounds like the dreaded UserPreferenceChanged event problem where a ui component has been created on a background thread without a message pump. The main ui thread synchronously sends the event to all registered ui windows and will hang because the ui component on the background worker thread is unable to process the UserPreferenceChanged event.
My app monitors a directory where users can upload a file. When a new file is detected it is added to a queue. I have a timer that runs through the queue and determines if the file has finished uploading. If there are any files that are complete it will take the most recent and begin running a background task (using BackgroundWorker).
My problem is that I don't know how to handle the timer while the background task is running. For example, if the timer is set to 10 seconds and the background worker is still working I want the timer to skip execution of another background worker until its next iteration.
Also, the information for each task is stored in the Queue (a ListView control) and I pass the ListViewItem to the background worker. I'm curious if passing the ListViewItem has any side effects.
Thanks!
You could store ready-to-process files in another queue (like a Queue< string> ) and have the BgWorker continuously poll that Queue. You might get better performance too, less idle time. You will have to protect the Queue (with Monitor) and have the BgWorker use Monitor.Wait when the Queue is empty.
To get an idea, look for Marc Gravell's answer on this question.
Really hard to answer this without seeing the code you are talking about. However, if you have to synchronize multiple asynchronous events (detecting a file is downloaded, adding the file to a queue, processing the queue) I suggest creating a single BackgroundWorker that does all tasks. Then it is easy in your worker to test what state each step is at. I would avoid creating multiple threads and attempting to synchronize them, this is very very problematic.
I would also not store any background task information in a UI data structure (like a ListView control). Create a callback or event in your BackgroundWorker that will alert the UI when it needs to display something.
Is the BackgroundWorker.IsBusy Property what you're looking for?
The simplest thing you could do is do all the work (including checking the folder) inside your BackgroundWorker: Check if you have something to do, if yes, do it, if not, use Sleep(time) or WaitOne(time) to suspend the thread for some time.
I don't think you need a thread-safe queue here, because folder is being updated asynchronously anyway. So you only need one thread, but you need a way to stop it. That is why AutoResetEvent.WaitOne(time) would be better than Sleep(time) - you can signal the event from the main thread to end your background worker earlier.
On your Timer.Tick handler, check the BackgroundWorker.IsBusy property to determine if it's ready for another bit of work or not. If not, just skip giving it the work and wait until the next Tick.
You can create a thread queue in which you place work-to-do. Your background worker loops around pulling off items from the queue and perform the work.
Some things need to be considered:
The queue needs to be thread safe, and quite likely you'd want the backgroundworker to block if the queue is empty, and wake up when an item becomes available. Im sure somone has made such a nice queue already.
The items you post to the queue will be operated on in another thread(the backgroundworker). Make sure this is done in a thread safe manner (e.g. don't post items to the queue that both the main application and the background worker will alter)
Another and easier approach is to
Queue up items in your application. Kick off the backgroundworker one first time.
When you get the event that the backgroundworker is done, pick the next item off the queue and start the backgroundworker again with this item.
You still need to care about thread safety. When you've sent an item to the backgroundworker, make sure only the backgroundworker operates on it(e.g. if you're just sending it strings, send it a copy of said string instead)
I didn't quite follow you on the timer. If the background worker is finished you should get an event and you'll know it's finished, no need for a timer to check this.
I currently have a thread that listens for data from the network and then runs rules on it. I then want to pass the data to the GUI. I am worried about having a deadlock in the GUI. I cant figure out were to put the mutexes on the GUI side. I am also using c# and dotnet 3.5.
What I have come up with is
1) Using a timer to create an event and dump the thread. Worried about performance.
2) Use an intermediary event to copy the data to GUI.
3) Dig in and figure out thread safe way of using GUI.
What do you think is best way to proceed?
Edit: Here is the solution I am using. I pass in the changed element and then protect the big object with a mutex. I use helper function to switch threads using InvokeRequired then BeginInvoke with a delegate. Pulled from reading the answers and then following links until reaching Threading in Windows Forms by Jon Skeet.
delegate void UInt32ParameterDelegate(UInt32 n);
public void UpdateLocation(UInt32 n)
{
if (InvokeRequired)
{
// We're not in the UI thread, so we need to call BeginInvoke
BeginInvoke(new UInt32ParameterDelegate(UpdateLocation), new object[] { n });
return;
}
// Must be on the UI thread if we've got this far
this.engine.location.UpdateBusy.WaitOne();
// do the work in here
this.engine.location.UpdateBusy.ReleaseMutex();
}
Synchronization is very easy in Windows Forms. You can call Control.Invoke() in the background thread. The thread will stall until the delegate has finished running on the UI thread. No sync required at all.
If stalling the thread is a problem, use Control.BeginInvoke(). You'll have to protect the object(s) you pass to the delegate with a lock if the thread might alter them while it continues running. That's rarely the case in a producer-consumer scenario, the thread can simply create new objects.
Do make sure that you don't Invoke() too often. Do it more frequently than about 1000 times per second and the UI thread will stop pumping Windows messages, being bogged down by handling the invoke requests. Since it is human eyes you're trying to please, invoking more than about 25 times per second is just wasted effort. Pool intermediate results in a collection object.
I hope I understand your problem correctly.
After the background thread reads the data and does whatever it wants, it should use Invoke to call a method on the GUI thread. That method would update anything that should be updated in the GUI.
Never read from the network on the GUI thread. It's only a matter of time before your application runs during a network outage and your GUI hangs as a result. This will really frustrate your users.
In your situation I think the best approach is to have a background thread complete the read operation. Then take the resulting data and move it back to the GUI thread via a SynchronizationContext Post or Send method.
you should just pass an event from your network thread to your UI thread.
then cross threads using begininvoke so you don't get a cross thread exception.
Need help getting info across a UI thread and another thread in C#
You could use a backgroundworker that will process the datareading in a background thread and when it's done you can end the backgroundworker triggering it's RunWorkerCompletedEventHandler. In the RunWorkerCompletedEventHandler you can update your GUI thread with the result.
Isn't easier to just throw a delegate who raise an event that inform the form to refresh itself?