Performance issues with background process WPF - c#

In my app I need a process that will work in the background and check for changes for various things. Then do some logic. Most of the time this process will be idle and just be waiting for the trigger point. So this is what I did:
private void MyBackgoroundThread()
{
while (isRunning)
{
if (MyStatus == 1)
{
//Log removed
}
}
}
Then at run time it would be called by the constructor with the follow;
await Task.Run(() => MyBackgoroundThread());
Now this works perfectly. The problem now is that my app when idle uses about 35% CPU usage. Disabling the MyBackgoroundThread the app uses 0% CPU usage at idle. So I know it's this thread.
I understand why this is happening but my question is what is best practice for handling this situation so I don't burn 35% CPU for doing nothing.
Edit: based on comments;
#Dour High Arch Explain what “the trigger point” is
Basically the variable MyStatus is a global variable that when the process has to be "triggered" the status gets change to 1 for example. Sorry thought was clear in the code.
#Ron Beyer This seems dangerous given that the "background" task is an
infinite loop, how is the await supposed to return?
Well you are at the meat of the issues. The global variable isRunning gets changed to false on the app closing. I am looking for a better solution

You are using 1 CPU, more or less, to constantly iterate your while statement.
The best solution depends on what you are doing in that code. If at all possible, use an event or similar notification to trigger background work rather than a polling thread. For example if you're looking for changes to files, use a FileSystemWatcher.
If your code, rather than an external agent, is causing the need to do work, you can also consider a Producer/Consumer pattern. In that case, have a look at BlockingCollection, which makes implementing that pattern a snap.
If there is no way to use an event-based notification mechanism to trigger the background work, you can use Thread.Sleep() to at least have your polling thread sleep for a time, until it has to wake up and check for work again.
UPDATE based on your edits
basically the variable MyStatus is a global variable that when the process has to be "triggered" the status gets change to 1 for example. Sorry thought was clear in the code.
Change it from a global variable to a static property, and have it fire off an event when the value is changed. Instead of using your polling thread, have some code that subscribes to your new event.
The global variable isRunning gets changed to false on the app closing.
A background thread will automatically close when the application closes.

Related

How to pause and resume a thread without use threading logic inside it

i cannot put threading logic inside of Run method, the run method executes many operation in database.
like this:
void Run()
{
while (true)
{
InsertEntitiesA();
DeleteEntitiesA();
UpdateEntitiesA();
InsertEntitiesB();
DeleteEntitiesB();
UpdateEntitiesB();
InsertEntitiesC();
DeleteEntitiesC();
UpdateEntitiesC();
}
}
if i pause it and the thread is on DeleteEntitiesB() i want it to stop there, and then when i resume i want it to start from where it's been stopped, DeleteEntitiesB() on the line it's been stopped.
is there a way to perform it?
i dont think there is =(
Ps: Like i said the Run method cannot be modified
You can do this using Thread.Suspend and Thread.Resume but it is generally a very bad idea. As you don't know where the thread is in its execution when you call these you have no idea whether it is in anything critical. If it is in something critical all sorts of havoc can ensue, this is probably why Microsoft decided to obsolete the methods.
It cannot be done without the thread's cooperation. What happens if you suspend the thread while it holds a critical lock? What if it holds a lock that the thread that is going to unsuspend it needs?

Strange if-statement behavior with zero value double

Would anyone care to explain to me how the value of this.oBalance.QouteBalance is evaluated to be true for being less than zero when it clearly isn't? Please see image below.
Am I missing something fundamental when it comes to comparing doubles in C#??
public double QouteBalance { get; set; }
UpdateBalance_PositionOpenned() is not being called in a loop, but is being called as part of a more complex event driven procedure that runs on the ticks of a timer (order of milliseconds)
EDIT: Pardon the code if it's messy but I couldn't edit it as this was a run-time error after quite a long run-time so was afraid wouldn't be able to recreate it. The Exception message is not correct and just a reminder for myself. The code after the exception is code I forgot to comment out before starting this particular run.
EDIT 2: I am building and running in Release Mode.
EDIT 3: Pardon my ignorance, but it would seem that I am in fact running in a multi-threaded environment since this code is being called as part of a more complex object method that gets executed on the ticks (Events) of a timer. Would it possible to ask the timer to wait until all code inside its event handler has finished before it can tick again?
EDIT 4: Since this has been established to be a multi-threading issue; I will try to give wider context to arrive at an optimized solution.
I have a Timer object, which executes the following on every tick:
Run a background worker to read data from file
When background worker finishes reading data from file, raise an
Event
In the event handler, run object code that calls the method below
(in the image) and other multiple routines, including GUI updates.
I suppose this problem can be avoided by using the timer Tick events to read the from file but changing this will break other parts of my code.
You're accessing shared variables from multiple threads. It's probably a race condition where one thread has thrown the error but by the time the debugger has caught and attached, the variable's value has changed.
You would need to look at implementing synchronizing logic like locking around the shared variables, etc.
Edit: To answer your edit:
You can't really tell the timer to not tick (well you can, but then you're starting and stopping and even after calling Stop you might still receive a few more events depending on how fast they are being dispatched). That said, you could look at Interlocked namespace and use it to set and clear and IsBusy flag. If your tick method fires and sees you're already working, it just sits out that round and waits for a future tick to handle work. I wouldn't say it's a great paradigm but it's an option.
The reason I specify using the Interlocked class versus just using a shared variable against comes down to the fact you're access from multiple threads at once. If you're not using Interlocked, you could get two ticks both checking the value and getting an answer they can proceed before they've flipped the flag to keep others out. You'd hit the same problem.
The more traditional way of synchronizing access to shared data member is with locking but you'll quickly run into problems with the tick events firing too quickly and they'll start to back up on you.
Edit 2: To answer your question about an approach to synchronizing the data with shared variables on multiple threads, it really depends on what you're doing specifically. We have a very small window into what your application is doing so I'm going to piece this together from all the comments and answers in hopes it will inform your design choice.
What follows is pseudo-code. This is based on a question you asked which suggests you don't need to do work on every tick. The tick itself isn't important, it just needs to keep coming in. Based on that premise, we can use a flagging system to check if you're busy.
...
Timer.Start(Handle_Tick)
...
public void Handle_Tick(...)
{
//Check to see if we're already busy. We don't need to "pump" the work if
//we're already processing.
if (IsBusy)
return;
try
{
IsBusy = true;
//Perform your work
}
finally
{
IsBusy = false;
}
}
In this case, IsBusy could be a volatile bool, it could be accessed with Interlocked namespace methods, it could be a locking, etc. What you choose is up to you.
If this premise is incorrect and you do in fact have to do work with every tick of the timer, this won't work for you. You're throwing away ticks that come in when you're busy. You'd need to implement a synchronized queue if you wanted to keep hold of every tick that came in. If your frequency is high, you'll have to be careful as you'll eventually overflow.
This isn't really an answer but:
UpdateBalance_PositionOpenned() is not being called in a loop, but is
being called as part of a more complex event driven procedure that
runs on the ticks of a timer (order of milliseconds)
see:
Multi-threading? – abatishchev 30 mins ago
Tight timer driven event-loop on the order of milliseconds probably has all the problems of threads, and will be almost entirely impossible to trouble-shoot with a step-through debugger. Stuff is happening way faster than you can hit 'F10'. Not to mention, you're accessing a variable from a different thread each event cycle, but there's no synchronization in sight.
Not really a full answer but too much for a comment
This is how I could code defensively
Local scope leads to less unexpected stuff
And it make code easier to debug and test
public void updateBalance(double amount, double fee, out double balance)
{
try
{
balance = amount * (1.0 + fee);
if (balance < 0.0) balance = 0.0;
}
catch (Exception Ex)
{
System.Diagnostics.Debug.WriteLine(Ex.Message);
throw Ex;
}
}
Value type is copied so even if then input variable for amount changed while the method was executing the value for amount in the method would not.
Now the out balance without locks is a different story.

How can a function be triggered with an event?

I have an application wherein I would like a function to be executed in the same thread when an event is fired. For example:
SomeCode()
{
// Do something...
// Fire event to run SomeOtherCode().
}
SomeOtherCode()
{
// Do something else...
}
I do not want to simply call the function because it will hold things up. SomeOtherFuction() needs to be executed in the same thread because it needs to access the form controls, and I need it to begin execution from an event trigger firing. I am using Microsoft Visual C# 2008 Express Edition. Thanks.
::: EDIT:::
Additional Details: The bottom line is that the contrustor of my form application is taking far too long to complete, and it is causing a significant delay, from when the user launches the application to when the application window appears on the display. This is not a problem on faster computers, but on slower computers it is a big problem. I need to exit the contrustor as soon as possible, thus allowing the framework to draw the application window, and continue initialization outside the constructor. (All essential items would still be initialized inside the constructor.)
An event-triggered function call would be ideal. I would prefer not to use a timer. Interlacing the affected code with Invokes is impractical in my situation and would require much more time to implement than I have to work on this. A simple example of an event-driven function call is all I'm really looking for. Thanks.
From your posts it's seems like you're confusing a few issues. The standard pattern in .Net is for events to run synchronously. The following lines are essentially identical in terms of when they execute.
Option #1
SomeCode();
SomeOtherCode();
Option #2
SomeEvent += delegate { SomeOtherCode(); }
...
SomeCode();
SomeEvent(this,EventArgs.Empty);
If you want to unblock the UI thread and run the code later you'll need to use some mechanism to delay the running of the SomeOtherCode function. The easiest way to do this in a WinForms application is to use a WinForms Timer instance. This will raise an event on the UI thread at a later point in time that you can respond to. It also won't block the UI thread during this time allowing your form to continue processing.
You seem to be asking to run SomeOtherCode() later.
You can call BeginInvoke (either from the UI thread or from any other thread) to queue a function to run during the next message loop:
BeginInvoke(new Action(SomeOtherCode));
It seems that you would want to add an event to the class that exposes the SomeCode method. Then, the class that implements the SomeOtherCode method would attach an event handler that calls the SomeOtherCode method.
It's completely viable to have this done in one class, in case you have some sort of state model where you want to add/remove the call depending on some other logic.
I think you want to put SomeOtherCode into a Task or BackgroundWorker, which would then synchronize with the UI thread to send it updates.
I recently posted on my blog a class that makes updating the UI from a Task as easy as from a BGW. I do recommend using Task rather than BackgroundWorker.
Simialr to what Stephen said, I would recommend that you move as much of that initialization code to a background thread or task. Let the background thread do as much work as possible, then send the necessary window updates to your UI thread via Action<>'s. Here's some quick psuedo-sample code:
protected void LoadMyListInBackground(object state)
{
List<string> myList = Databse.FetchMyList(myParameters); // This take a while, so the UI thread isn't waiting
ShowMyList(myList);
}
protected void ShowMyList(List<string> theList)
{
if(InvokeRequired)
Invoke(new Action<List<string>>(ShowMyList, theList);
else
{
foreach(string item in theList)
myListBox.Items.Add(item);
}
}
In this example the UI thread is free to keep drawing your window while the background thread does the lengthy database work. The problem is, even if you fire an event outside of your constructor, and that event occurs on the UI thread and takes a long time, the user might see the window but that window is going to 'freeze' and possibly appear to be 'crashed' to the user. This technique prevents that and provides a better user experience.

How can I check if a function is being called on a particular Thread?

If I have Thread A which is the main Application Thread and a secondary Thread. How can I check if a function is being called within Thread B?
Basically I am trying to implement the following code snippit:
public void ensureRunningOnCorrectThread()
{
if( function is being called within ThreadB )
{
performIO()
}
else
{
// call performIO so that it is called (invoked?) on ThreadB
}
}
Is there a way to perform this functionality within C# or is there a better way of looking at the problem?
EDIT 1
I have noticed the following within the MSDN documentation, although Im a dit dubious as to whether or not its a good thing to be doing! :
// if function is being called within ThreadB
if( System.Threading.Thread.CurrentThread.Equals(ThreadB) )
{
}
EDIT 2
I realise that Im looking at this problem in the wrong way (thanks to the answers below who helped me see this) all I care about is that the IO does not happen on ThreadA. This means that it could happen on ThreadB or indeed anyother Thread e.g. a BackgroundWorker. I have decided that creating a new BackgroundWorker within the else portion of the above f statement ensures that the IO is performed in a non-blocking fashion. Im not entirely sure that this is the best solution to my problem, however it appears to work!
Here's one way to do it:
if (System.Threading.Thread.CurrentThread.ManagedThreadId == ThreadB.ManagedThreadId)
...
I don't know enough about .NET's Thread class implementation to know if the comparison above is equivalent to Equals() or not, but in absence of this knowledge, comparing the IDs is a safe bet.
There may be a better (where better = easier, faster, etc.) way to accomplish what you're trying to do, depending on a few things like:
what kind of app (ASP.NET, WinForms, console, etc.) are you building?
why do you want to enforce I/O on only one thread?
what kind of I/O is this? (e.g. writes to one file? network I/O constrained to one socket? etc.)
what are your performance constraints relative to cost of locking, number of concurrent worker threads, etc?
whether the "else" clause in your code needs to be blocking, fire-and-forget, or something more sophisticated
how you want to deal with timeouts, deadlocks, etc.
Adding this info to your question would be helpful, although if yours is a WinForms app and you're talking about user-facing GUI I/O, you can skip the other questions since the scenario is obvious.
Keep in mind that // call performIO so that it is called (invoked?) on ThreadB implementation will vary depending on whether this is WinForms, ASP.NET, console, etc.
If WinForms, check out this CodeProject post for a cool way to handle it. Also see MSDN for how this is usually handled using InvokeRequired.
If Console or generalized server app (no GUI), you'll need to figure out how to let the main thread know that it has work waiting-- and you may want to consider an alternate implementation which has a I/O worker thread or thread pool which just sits around executing queued I/O requests that you queue to it. Or you might want to consider synchronizing your I/O requests (easier) instead of marshalling calls over to one thread (harder).
If ASP.NET, you're probably implementing this in the wrong way. It's usually more effective to use ASP.NET async pages and/or to (per above) synchronize snchronizing to your I/O using lock{} or another synchronization method.
What you are trying to do is the opposite of what the InvokeRequired property of a windows form control does, so if it's a window form application, you could just use the property of your main form:
if (InvokeRequired) {
// running in a separate thread
} else {
// running in the main thread, so needs to send the task to the worker thread
}
The else part of your snippet, Invoking PerformIO on ThreadB is only going to work when ThreadB is the Main thread running a Messageloop.
So maybe you should rethink what you are doing here, it is not a normal construction.
Does your secondary thread do anything else besides the performIO() function? If not, then an easy way to do this is to use a System.Threading.ManualResetEvent. Have the secondary thread sit in a while loop waiting for the event to be set. When the event is signaled, the secondary thread can perform the I/O processing. To signal the event, have the main thread call the Set() method of the event object.
using System.Threading;
static void Main(string[] args)
{
ManualResetEvent processEvent = new ManualResetEvent(false);
Thread thread = new Thread(delegate() {
while (processEvent.WaitOne()) {
performIO();
processEvent.Reset(); // reset for next pass...
}
});
thread.Name = "I/O Processing Thread"; // name the thread
thread.Start();
// Do GUI stuff...
// When time to perform the IO processing, signal the event.
processEvent.Set();
}
Also, as an aside, get into the habit of naming any System.Threading.Thread objects as they are created. When you create the secondary thread, set the thread name via the Name property. This will help you when looking at the Threads window in Debug sessions, and it also allows you to print the thread name to the console or the Output window if the thread identity is ever in doubt.

Invoke() is blocking

From time to time my applications GUI stops redrawing.
There a lot of threads that are firing all kinds of events (like timers or network data ready etc.). Also there are a lot of controls that are subscribing these events. Because of that, all the event handlers play the InvokeRequired/Invoke game.
Now I figured out that when the GUI freezes a lot of threads are waiting for Invoke() to return. Looks like the message pump stopped pumping.
The handlers look like this:
private void MyEventHandler( object sender, EventArgs e ) {
if ( InvokeRequired ) {
Invoke( new EventHandler( MyEventHandler ), sender, e );
return;
}
SetSomeStateVariable();
Invalidate();
}
Any ideas?
Solution: BeginInvoke(). Looks like you should always use BeginInvoke() if you have lots of CrossThread-Events...
Thanks.
Thanks everybody.
EDIT: Looks like BeginInvoke() really solved it. No freezing until now.
Invoke waits until the event is handled in the GUI thread. If you want it to be asynchronous use BeginInvoke()
Deadlock perhaps? Do you make sure that the events are never fired while holding a lock?
Are you able to see this with a debugger attached? If so, make it freeze and then hit the "pause" button - and see what the UI thread is doing.
Note that if you are able to get away with BeginInvoke instead of Invoke, life is a bit easier as it won't block.
Also note that you don't need the "new EventHandler" bit - just
Invoke((EventHandler) MyEventHandler, sender, e);
should be fine.
From watching this question, I can see that you're not going to get any answers that will fix the problem immediately, as most of them require you to debug the event, and it happens so infrequently that this is nearly impossible. So, let me suggest you make some code changes that might help you identify the culprit in the field.
I suggest that you create a static class whose sole purpose is to handle all your Invoke calls. I would suggest that this class has a method that takes a Control, (to call Invoke on) an Action (the method to be invoked), and a description (containing the information you would need to know to identify the method and what it is going to do).
Within the body of this method, I suggest you enqueue this information (method, description) and return immediately.
The queue should be serviced by a single thread, which pops the action/message pair off the queue, records the current time and the Action's description in a pair of properties, and then Invokes() the Action. When the Action returns, the description and time are cleared (your DateTime can be nullable, or set it to DateTime.Max). Note, since all Invokes are marshalled one at a time onto the UI thread, you're not losing anything by servicing the queue by a single thread here.
Now, here's where we get to the point of this. Our Invoking class should have a heartbeat System.Threading.Timer thread. This should NOT be a windows.forms.timer object, as that runs on the UI thread (and would be blocked when the ui is blocked!!!).
The job of this timer is to periodically peek at the time the current Action was Invoked. If DateTime.Now - BeginTime > X, the heartbeat timer will decide that this Action has blocked. The heartbeat timer will LOG (however you log) the DESCRIPTION recorded for that Action. You now have a recording of what was happening at the time your UI locked up and can debug it better.
I know it's not an answer to your problem, but at least by doing this you can get a good idea about what's going on at the time you're blocked.
The most likely answer (deadlock) has already been suggested.
Another way to simulate this behaviour is to reduce the number of pool threads and IO completion ports; you haven't called ThreadPool.SetMaxThreads(...) by any chance?

Categories

Resources