Async process start and wait for it to finish

后端 未结 5 1015
小鲜肉
小鲜肉 2020-11-27 15:31

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 th
相关标签:
5条回答
  • 2020-11-27 16:09

    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
    }
    
    0 讨论(0)
  • 2020-11-27 16:12

    "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
        }
    });
    
    0 讨论(0)
  • 2020-11-27 16:25

    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

    0 讨论(0)
  • 2020-11-27 16:30

    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.

    0 讨论(0)
  • 2020-11-27 16:34

    Adding an advanced alternative to this old question. If you want to wait for a process to exit without blocking any thread and still support timeouts, try the following:

        public static Task<bool> WaitForExitAsync(this Process process, TimeSpan timeout)
        {
            ManualResetEvent processWaitObject = new ManualResetEvent(false);
            processWaitObject.SafeWaitHandle = new SafeWaitHandle(process.Handle, false);
    
            TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>();
    
            RegisteredWaitHandle registeredProcessWaitHandle = null;
            registeredProcessWaitHandle = ThreadPool.RegisterWaitForSingleObject(
                processWaitObject,
                delegate(object state, bool timedOut)
                {
                    if (!timedOut)
                    {
                        registeredProcessWaitHandle.Unregister(null);
                    }
    
                    processWaitObject.Dispose();
                    tcs.SetResult(!timedOut);
                },
                null /* state */,
                timeout,
                true /* executeOnlyOnce */);
    
            return tcs.Task;
        }
    

    Again, the advantage to this approach compared to the accepted answer is that you're not blocking any threads, which reduces the overhead of your app.

    0 讨论(0)
提交回复
热议问题