views:

54

answers:

3

I want to scan a queue every 10 seconds using a Timer. If there are more then 0 items in this queue then Deque the first one, pass it as an argument to a Process and run that process. The timer should be disabled while this process executes. Once the process exits, it should re-enable the timer.

The items in the queue can be added manually or can come from a database.

The following C# code does not works after the first process is finished. For some reason the timer is not enabled again. Can somebody help?

public MainForm()
{
    InitializeComponent();

    queue = new Queue<string>();
    process = new Process();
    process.Exited += new EventHandler(Process_Exited);
    process.EnableRaisingEvents = true;
}

void StartProcess(string args)
{
    ProcessStartInfo psi = new ProcessStartInfo();
    psi.FileName = @"C:\Program Files\My Software\RunProcess.exe";
    psi.Arguments = args;
    psi.WindowStyle = ProcessWindowStyle.Minimized;

    process.StartInfo = psi;
    process.Start();
}

void Process_Exited(object sender, EventArgs e)
{
    timer.Enabled = true;
}

void Timer_Tick(object sender, EventArgs e)
{
    if (queue.Count > 0)
    {
        timer.Enabled = false;
        StartProcess(queue.Dequeue());
    }
}
A: 

Consider using Process.WaitForExit() instead of handling the Exited event. This way, you can set a timeout value (in case the process never exits) and you can start/stop the timer from within the Timer_Tick() method.

Bradley Smith
The process can run for a variable amount of time based upon the volume of data it has to process. The problem is that it cannot run in parallel, that is why I have to make a queue. The time taken by this process can be between 30 seconds and 3 hours. During which my software has to do other tasks too, so can't use WaitForExit().
Imran S.
+1  A: 

I didn't look up the details for lack of time but I found out that dispatching timer.Enabled = true; to the UI thread will do the trick.

EDIT: Just checked MSDN: "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. "

Roland Sommer
A: 

Any luck with:

timer.AutoReset = true;

?

Matt Jacobsen