In my code below, I am using Process objects to execute a series of DOS batch files.
I’m shortening the list of scripts for example’s sake.
The subsequent (1+) scripts execute via an event handler (instead of a for loop). That way, each subsequent script runs ONLY when the previous one finishes. Now for some reason as I execute the 2nd script I can’t get the caught exception to populate the status bar with the error message.
I’m testing for when invalid script names are entered in an app-config file, and I suspect I am using delegates incorrectly. My anonymous delegate consists of a combination of “new code” and existing class methods. Thats what I think is wrong; If you all could shove me toward a why I’d appreciate it 😉
NOTE: this.copy_scripts[] is constructued from a Split of: “goodname.bat,nosuchscript.bat”
private void copybutton_Click(object sender, EventArgs e)
{
InitializeBar();
this.nbr_of_copy_exits_ = 0;
this.RunCopyScript(this.nbr_of_copy_exits_);
return;
}
private void RunCopyScript(Int32 CopyScriptIdx)
{
Process proc = null;
try
{
proc = this.ObtainProcess(this.client_dest_dir_ + this.copy_scripts_[CopyScriptIdx]);
proc.EnableRaisingEvents = true;
proc.Exited += new EventHandler(CopyExited);
proc.Start();
this.progressBar.Value = ProgressInPercent(this.copy_scripts_.Count(), CopyScriptIdx);
}
catch (Exception ex)
{
this.UpdateControl(this.toolStripStatusLabel1, "Error involving " + this.copy_scripts_[CopyScriptIdx] + ": " + ex.Message);
this.copybutton.BackColor = Color.Red;
}
return;
}
void CopyExited(object sender, EventArgs e)
{
System.Diagnostics.Process senderProcess
= sender as System.Diagnostics.Process;
this.Invoke((MethodInvoker)delegate
{
if (++this.nbr_of_copy_exits_ == this.copy_scripts_.Count())
{
this.UpdateControl(this.toolStripStatusLabel1, "Copying COMPLETE.");
this.progressBar.Value = 0;
}
else
{
this.RunCopyScript(this.nbr_of_copy_exits_);
}
});
}
private void UpdateControl(ToolStripStatusLabel tssl, String text)
{
tssl.Text = text;
tssl.Refresh();
}
I think that rather than using an event to setup and continue the loop, I would create an asynchronous delegate with a callback method. When the process is complete you simply call back to the
RunCopyScript(...)again. Take a look at delegates on MSDN, and asynchronous programming. I’m sure someone will have a way of doing this withAction, I just don’t know it well enough to give you an example.I also saw a neat snippet on how to get the output into a gui control element from a cross-threaded function. Unfortunately, I cannot find the elegant piece of coding that I saw earlier…if I do run across it, I’ll post a link to it.
Okay, here is what I have – for what it’s worth. I believe it is fairly accurate. I would not expect that it would compile out-of-the-box as I don’t have all the files, paths, etc. to properly start processes. And setting up simulated batch files to
Start()aProcesswould take quite a bit more work. I expect you should be able to work with this and have something closer to what you want if cross-referenced with the link I provided above.I also commented out some lines of code that wouldn’t be needed, I moved, or were not recognized. In addition, I did not do anything with your current
try/catchblock.As I stated, there are more elegant implementations using Action delegates which I am sure can be asynchronous. I hope that someone provides an example.