views:

3054

answers:

4

I am new to the thread model in .net. What would you use to:

  1. start a process that handles a file (process.StartInfo.FileName = fileName;)
  2. wait for the user to close the process OR abandon the thread after some time
  3. if the user closed the process, delete the file

Starting the process and waiting should be done on a different thread than the main thread, because this operation should not affect the application.

Example:

My application produces an html report. The user can right click somewhere and say "View Report" - now I retrieve the report contents in a temporary file and launch the process that handles html files i.e. the default browser. The problem is that I cannot cleanup, i.e. delete the temp file.

+4  A: 

"and waiting must be async" - I'm not trying to be funny, but isn't that a contradiction in terms? However, since you are starting a Process, the Exited event may help:

        ProcessStartInfo startInfo = null;
        Process process = Process.Start(startInfo);
        process.EnableRaisingEvents = true;
        process.Exited += delegate {/* clean up*/};

If you want to actually wait (timeout etc), then:

if(process.WaitForExit(timeout)) {
    // user exited
} else {
    // timeout (perhaps process.Kill();)
}

For waiting async, perhaps just use a different thread?

        ThreadPool.QueueUserWorkItem(delegate {
            Process process = Process.Start(startInfo);
            if(process.WaitForExit(timeout)) {
                // user exited
            } else {
                // timeout
            }
        });
Marc Gravell
A: 

Try the following code.

public void KickOffProcess(string filePath) {
  var proc = Process.Start(filePath);
  ThreadPool.QueueUserWorkItem(new WaitCallBack(WaitForProc), proc);
}

private void WaitForProc(object obj) {
  var proc = (Process)obj;
  proc.WaitForExit();
  // Do the file deletion here
}
JaredPar
Not sure it handles the "OR abandon the thread after some time"
Marc Gravell
A: 

I would probably not use a separate process for opening a file. Instead, I'd probably utilize a background thread (if I thought the operation was going to take a long time and possible block the UI thread).

private delegate void FileOpenDelegate(string filename);

public void OpenFile(string filename)
{
   FileOpenDelegate fileOpenDelegate = OpenFileAsync;
   AsyncCallback callback = AsyncCompleteMethod;
   fileOpenDelegate.BeginInvoke(filename, callback, state);
}

private void OpenFileAsync(string filename)
{
   // file opening code here, and then do whatever with the file
}

Of course, this is not a good working example (it returns nothing) and I haven't shown how the UI gets updated (you have to use BeginInvoke at the UI level because a background thread cannot update the UI thread). But this approach is generally how I go about handling asynchronous operations in .Net.

Chris Holmes
Sorry, actually I meant that the process should handle the file, not open it. I rewrote the question.
Bogdan Gavril
A: 

You can use the Exited event in Process class

ProcessStartInfo info = new ProcessStartInfo();

info.FileName = "notepad.exe";
Process process = Process.Start(info);

process.Exited += new EventHandler(process_Exited);
Console.Read();

and in that event you can handle the operations you mentioned

pablito
this isn't async
Bogdan Gavril