C# - Only run immediate function with threading? - c#

Here's what I have. When my application starts up, it creates a thread and runs my startListening() function. But what it seems to do, is run any other functions called within startListening under the same thread. Is there a way I can make it so that ONLY the things immediately inside of startListening are ran with that thread, and not the functions called from within that?
It would just make it a lot easier for me when referencing controls and things that aren't within that thread so I don't have to Invoke each time.
EDIT: Maybe this isn't the right thing to be asking. I know I had to Invoke with setting textboxes, but now I need to make a timer enabled. Its not throwing any exceptions when I try to enable it, but rather just not "ticking". Here's my code:
private void beginListenerThread()
{
Thread thread1 = new Thread(startListening);
thread1.Start();
}
private void startListening()
{
timer1.enabled = true;
}
But it doesn't tick.
Thanks!

No, that's not possible automatically. If you are able to modify the method that should be called on another thread, change the calls to other methods so that they're run on the originating thread. If you're using Windows Forms, use this.Invoke or this.BeginInvoke, for example.

Yes, this is the kind of trouble you'll run into when you use a class that is not thread-safe on a thread. The Winforms Timer class generates Tick events from a little hidden helper window, a window that receives WM_TIMER messages generated by the Windows SetTimer() api function and turns them into Tick event calls. That window is created when you enable the timer.
What goes wrong here is that this window gets created on the wrong thread. It needs a message pump to dispatch the WM_TIMER notifications, that thread doesn't have one. It could have one by calling Application.Run() but you don't want to go there.
Follow the advice given in the MSDN Library article's Remarks section:
The Windows Forms Timer component is single-threaded, and is limited to an accuracy of 55 milliseconds. If you require a multithreaded timer with greater accuracy, use the Timer class in the System.Timers namespace.
Or the System.Threading.Timer class, a timer class that's a bit less cranky.

Related

How to call a method Asynchronously?

I have created an application in windows form. Once I submit the application, the application get processed. I have created a class library which process the application and move the submitted application to different workflows. For this I have called the Class library from the click event of the Submit button. Everything is working fine, but the only problem is that once I submit the application and it calls the class library, it takes some time as it processes it. I want that the application should get closed and it calls the library method asynchronously. Below is the code:
private void OnPASubmit_Click(object sender, EventArgs e)
{
if ((ApplAcct.AcctID == 0) || CheckForChanges())
{
UIHelper.ShowMessage("Please Save Application first");
return;
}
try
{
if (!AOTHelper.ValidateCheckOut(ApplAcct.AcctID))
{
return;
}
WorkflowTask.PutAccountWorkflowTask(ApplAcct.AcctID, AOTHelper.FindAcctGUID(Main.objAccountGUID, Acct.AcctID), Environment.UserName, 2);
AOTHelper.checkInAccount(ApplAcct.AcctID);
AOTHelper.AccountToProcess(Acct.AcctID);
UIHelper.ShowMessage("Application has been submitted for processing.");
this.Close();
}
catch (Exception ex)
{
AOTHelper.WriteLog(ex, "Can not submit application for processing ");
}
// ...
}
The AotHelper.AccountToProcess(Acct.AcctID), method calls the class library and I want to do this with the help of Asunchronous calling so that the application doesn't have to wait for processing once it get submitted.
How will I do it. Please help!
Multiple ways to run asynchronous, such as TPL, starting your own thread (and in the 4.5 framework await), but for winforms perhaps the easiest way is to add a BackGroundWorker component. You can just drag/drop one from the toolbox on your designer.
Double clicking the added component, automatically creates a method that catches the DoWork event of the backgroundworker, you can place your code there. Then in the submit button you only have to call
backgroundWorker.RunWorkerAsync();
Then you should use BackgroundWorker class.
You can use BackgroundWorker thread...
BackgroundWorker makes threads easy to implement in Windows Forms. Intensive tasks need to be done on another thread so that the UI doesn't freeze. It is necessary to post messages and update the user interface when the task is done.
When you use the BackgroundWorker class, you can indicate operation progress, completion, and cancellation in the user interface. For example, you can check whether the background operation is completed or canceled and display a message to the user.
Read a simple tutorial
Here is a good example:
http://www.ricky-dev.com/2012/05/throttled-processing-of-multiple-asynchronous-tasks/
Several ways. You can start a background worker thread that calls the process and just ends when it's done.
You could create a delegate and use the BeginInvoke.
You could send a message that a listener in a service picks up on a depatches a process to run it.
Lots of ways to skin that cat.
Here is an old but useful MSDN ref http://msdn.microsoft.com/en-us/magazine/cc301332.aspx
You simply need to start it on a separate thread. For instance:
Thread thread = new Thread(new ParameterizedThreadStart(AOTHelper.AccountToProcess));
thread.Start(Acct.AcctID);
If you are going to be starting many threads at the same time, though, you should use a thread pool, instead.
You need to be careful, though. The method you call on the separate thread cannot do anything with the UI or it will throw an exception. If it needs to do something to the UI, it will need a reference to a form or control so it can call that object's Invoke method to get back on the UI thread. Also, since it is happening asynchronously, you will no longer be able to show that message box immediately after calling it because that will show immediately before the work is done.
I want that the application should get closed and it calls the library
method asynchronously.
If you want to submit the data before the application is closed then modify the event that handles when a form is about to close. Please understand this event only happens if the form is closed by the user. If you want to cover when the process is forced to exit you have to subscribe to that event and so something similar.
Furthermore there are ways to close a process and for none of these events to happen. Basically this solution only works if the process reports back to Windows that it is closing.
Of course you shouldn't submit data asynchronously if your program's process is about to end.

Should I use background workers or timers in this situation?

I am writing a program that manages a bunch of timers.
The user has to start them manually, and is able to get information from each timer, to know the remaining time for example.
I don't want the GUI to freeze, therefore I don't want to have a timer on the main form thread that freezes the whole thing.
So, does the Timer class send the timer on a new thread, or it keeps it on the main UI thread?
Otherwise, should I use a Background Worker to accomplish this?
The System.Windows.Forms.Timer event runs on the UI thread.
Instead you can use a System.Threading.Timer which runs on a worker thread.
Ref. : Comparing the Timer Classes in the .NET Framework Class Library
Depends on the type timer you use, I suggest to read these articles to decide the best for you.

Does the System.Windows.Forms.Timer run on a different thread than the UI?

I have a main thread that creates a form object which creates and sets a timer to run a function named updateStatus() every minute. But updateStatus() is also called by the main thread at several places.
However, I am not clear about whether or not it will cause any synchronization problems. Does the System.Windows.Forms.Timer in C# run on a different thread other than the main thread?
No, the timer events are raised on the UI thread.
You won't have any synchronicity problems. This is the correct version of the timer control to use in a WinForms application; it's specifically designed to do what you're asking. It's implemented under the hood using a standard Windows timer.
The documentation confirms this in the Remarks section:
A Timer is used to raise an event at user-defined intervals. This Windows timer is designed for a single-threaded environment where UI threads are used to perform processing. It requires that the user code have a UI message pump available and always operate from the same thread, or marshal the call onto another thread.
When you use this timer, use the Tick event to perform a polling operation or to display a splash screen for a specified period of time. Whenever the Enabled property is set to true and the Interval property is greater than zero, the Tick event is raised at intervals based on the Interval property setting.
No, the timer's Tick event is raised from the UI thread by the message loop when it receives a WM_TIMER message. You're always good with that, it can only run when your UI thread is idle.
No.
The whole point of a Windows.Forms Timer is that it runs on the GUI Thread.
Windows (WinForms) runs something called the MessagePump (see Application.Run()) and this is what makes the Timer possible.
All your code runs as part of an Eventhandler somehow, and a Timer tick will never 'interrupt' any other event handler.
The Windows.Forms timer raises the event back on the UI thread, presumably via the sync-context.
If you want a non-UI thread, there are other timers - for example System.Timers.Timer or System.Threading.Timer
According to the documentation it runs on the main UI thread:
A Timer is used to raise an event at
user-defined intervals. This Windows
timer is designed for a
single-threaded environment where UI
threads are used to perform
processing. It requires that the user
code have a UI message pump available
and always operate from the same
thread, or marshal the call onto
another thread.
I don't want to impeach the reputation of others how has answered, that Windows.Forms.Timer does always run on GUI thread, but I have to contradict. :)
I would answer - it depends. It can be, that Windows.Forms.Timer does run on Non-GUI thread!
Windows.Forms.Timer does fire it's Timer.Tick event on the thread, where the Form, which contains the timer, has been created.
If the form is created on the GUI thread, then the Timer.Tick runs on GUI thread, if however Form is created on the e.g. some thread XXX from thread pool(what you should avoid), then the Timer.Tick runs on this XXX thread.
Task.Run(()=>
{
using (var formWithTimer = new SomeFormWithTimer()) //Form created on worker thread, Tick handled on it.
{
formWithTimer.ShowDialog();
}
});

Porting SetTimer() and KillTimer() to C#?

I am trying to port some code from C++ to C#.
I came across this in the C++ code:
watchdogTimer = SetTimer(1,1000,NULL);
...
KillTimer(watchdogTimer);
What is this code doing, and how can this be ported to C#?
Thanks.
The CWnd::SetTimer function you're looking at creates a timer that sends WM_TIMER events to the window. This is analogous to the System.Windows.Forms.Timer component in .NET. It behaves somewhat differently than the System.Timers.Timer. There are two differences that are particularly relevant:
Windows.Forms.Timer calls the event handler on the UI thread. By default, System.Timers.Timer calls the event handler on a threadpool thread. You can use SynchronizingObject property to have the System.Timers.Timer call on the UI thread.
Another difference is that it's not possible to encounter reentrancy problems with the Windows Forms timer because Windows won't allow multiple WM_TIMER messages from the same timer in the queue, nor will it place a WM_TIMER message in the queue if one is already being processed. This is generally a good thing.
System.Timers.Timer, on the other hand, will allow reentrancy. So if your timer event handler takes longer than the timer period, you can be processing multiple events for the same timer concurrently. If your timer period is 100 ms and processing takes 150 ms, you're going to get another notification while you're processing the first one. If you use the SynchronizingObject to force the callback on the UI thread, this can lead to a whole bunch of pending callbacks being queued.
The implementation of the two timers is quite different. The Windows Forms timer uses old style Windows timers that have been around for 20 years. This type of timer requires a window handle and a message loop, and is therefore used only in GUI programs. System.Timers.Timer is a thin wrapper around System.Threading.Timer, which uses the Windows Thread Pool Timers.
Assuming that your application is written under MFC, the SetTimer() method belongs to class CWnd and is responsible for setting up a windows timer. Documentation for this can be found at http://msdn.microsoft.com/en-us/library/49313fdf(v=vs.80).aspx. I know little about .NET but a quick google search located the following this: http://msdn.microsoft.com/en-us/library/0tcs6ww8(v=VS.90).aspx.

Performing periodic audits and best practice

I'm doing a windows form and would like an audit task to happen every 30 seconds. This audit is essentially checking a series of services on remote computers and reporting back into a richtextbox the status.
Current I have this running in an endless background thread and using an invoker to update the richtextbox in the main form.
Is this best practice? If I made an endless loop in my main form that would prevent any of my buttons from working, correct?
I'm just curious if every time I want to create a periodic audit check I have to create a new thread which checks the status or file or what have you?
Edit: I looked further into the Timer class and decided to go with System Timer as it proved to be better with a longer function. Thanks for pointing me in the right direction.
You should look into the Windows Forms Timer class. You don't want a loop in your main form. It's better to use the timer to fire events which can be processed asynchronously on another thread.
(I assume this is a winform application)
Invoking on the main thread is the way to go. But what about using a timer instead of an endless loop? It gives you more control. And a the timer function would execute on it's own thread.
It's good practice to let long going work execute on a background thread, so that the main thread can work with the UI.

Categories