HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Using Timer with Backgroundworker to ensure the doWork method is called

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
thecalledmethodwithensuretimerusingbackgroundworkerdowork

Problem

I have a windows forms application in which a backgroundworker is called again and again.
I need to avoid concurrent access of the code in dowork method for the backgroundWorker; but also need to ensure that the code in the dowork method is called; hence I cannot simply avoid running the backgroundworker altogether if it is busy.

The code is provided below with detailed comments:
The code as it is works nicely; Please evaluate the code and this way of achieving the intended; Please let me know of any potential problems,code smells, design flaws or better way of doing this. Any kind of comments, answers will be of great help.

```
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Threading;

namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
// this timer calls bgWorker again and again after regular intervals
System.Windows.Forms.Timer tmrCallBgWorker;

// this is our worker
BackgroundWorker bgWorker;

// this is the timer to make sure that worker gets called
System.Threading.Timer tmrEnsureWorkerGetsCalled;

// object used for safe access
object lockObject = new object();

public Form1()
{
InitializeComponent();
// this timer calls bgWorker again and again after regular intervals
tmrCallBgWorker = new System.Windows.Forms.Timer();
tmrCallBgWorker.Tick += new EventHandler(tmrCallBgWorker_Tick);
tmrCallBgWorker.Interval = 100;

// this is our worker
bgWorker = new BackgroundWorker();
// work happens in this method
bgWorker.DoWork += new DoWorkEventHandler(bg_DoWork);
bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bg_RunWorkerCompleted);

}

void bg_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Complete");
}

void bg_DoWork(object sender, DoWorkEventArgs e)
{
// does a job li

Solution

I needed something similar, in that I had code that was going to periodically check the database for new records and notify the user with baloon tips. Checking the database every n-secs caused a pause in the UI that I didn't want the user to experience so I moved the procedure to a thread.

I had a System.Windows.Forms.Timer tick event, where the Thread was created something like (leaving out all the exception handling etc):

TIMER_TICK(object sender, EventArgs){
    Thread checkNow=new Thread(ProcessAutoCheck)
    checkNow.IsBackground=true;
    checkNow.Start();
    checkNow.Join(500);
}


Then in the ProcessAutoCheck method, I used the lock approach to prevent thread contention:

**lock**(lockObject){
{
....


The program worked as designed, and I didn't consume resources with threads. It wasn't the fanciest solution. I learned a lot from Threading in C# - By Joseph Albahari. Complete book online.

Code Snippets

TIMER_TICK(object sender, EventArgs){
    Thread checkNow=new Thread(ProcessAutoCheck)
    checkNow.IsBackground=true;
    checkNow.Start();
    checkNow.Join(500);
}
**lock**(lockObject){
{
....

Context

StackExchange Code Review Q#3985, answer score: 5

Revisions (0)

No revisions yet.