Tại sao phương thức Exited của quy trình của tôi không được gọi?


96

Tôi có mã sau đây, nhưng tại sao ProcessExitedphương thức không bao giờ được gọi? Nó cũng giống như vậy nếu tôi không sử dụng Windows shell ( startInfo.UseShellExecute = false).

ProcessStartInfo startInfo = new ProcessStartInfo();
startInfo.CreateNoWindow = true;
startInfo.UseShellExecute = true;
startInfo.WindowStyle = ProcessWindowStyle.Hidden;
startInfo.FileName = path;
startInfo.Arguments = rawDataFileName;
startInfo.WorkingDirectory = Util.GetParentDirectory(path, 1);

try
{
     Process correctionProcess = Process.Start(startInfo);
     correctionProcess.Exited += new EventHandler(ProcessExited);                   

     correctionProcess.WaitForExit();

     status = true;
}

.....

internal void ProcessExited(object sender, System.EventArgs e)
{
      //print out here
}

Câu trả lời:


241

Để nhận được cuộc gọi lại khi Exitedsự kiện, sự kiện EnableRaisingEventsphải được đặt thành true.

Process correctionProcess = Process.Start(startInfo);
correctionProcess.EnableRaisingEvents = true;
correctionProcess.Exited += new EventHandler(ProcessExited); 

3
fixProcess.WaitForExit (), không có chức năng này thì mã này không hoạt động đối với tôi
Kira

7
Một mẹo nhỏ (đặc biệt đối với những người không phải là chuyên gia C #): đừng Close()quá trình này! Tôi đã gặp sự cố không liên tục với trình xử lý Exit do nỗ lực quản lý tài nguyên sai lầm. Mã được đề cập được gọi Process.Close()sau Process.Start(startInfo), thay vì cho phép GC thu thập nó theo đúng quy trình. Dễ nhầm lẫn nếu nền của bạn là ngôn ngữ không phải GC (ví dụ: C / C ++).
Jerzy

3
Tuyệt quá. Cảm ơn. Tôi cũng muốn lưu ý rằng việc chỉ định EnableRaisingEventsEventHandlersphải được thực hiện chính xác sau Process.Start(). Nó sẽ không hoạt động khác.
Doruk

2
@Doruk Tôi có thể đặt EnableRaisingEvents=truetrước khi gọi Process.Start()và nó hoạt động tốt.
Action Dan

29

Từ MSDN :

Sự kiện Exited chỉ ra rằng quá trình liên quan đã thoát. Sự xuất hiện này có nghĩa là quá trình đã kết thúc (bị hủy bỏ) hoặc đã đóng thành công. Sự kiện này chỉ có thể xảy ra nếu giá trị của thuộc tính EnableRaisingEvents là true.

Bạn đã đặt thuộc tính đó thành true chưa?


19
Đó là một lá cờ rất un-idomatic, quá (việc sử dụng là những gì dù sao, nếu tôi không muốn sự kiện này, tôi không đăng ký vào nó!)
Tamás Szelei

3
Không trực quan lắm. Cần nêu rõ ràng trong mỗi mô tả sự kiện rằng nó yêu cầu đặt cờ này.
TheLegendaryCopyCoder

18

Bạn phải đặt Process.EnableRaisingEventsthành true.



9

Tôi đã xem qua các ví dụ đặt new Process()trong một usingmệnh đề. Đừng làm điều đó nếu bạn muốn sử dụng Exitedtính năng. Các usingđiều khoản phá hủy các trường hợp cùng với bất kỳ xử lý sự kiện trên Exited.

Điều này...

using(var process = new Process())
{
   // your logic here
}

Nên là ...

var process = new Process();

Tôi cũng nhận thấy điều đó. Thật kỳ lạ, các sự kiện OutputDataReceive hoạt động tốt. Hoặc có thể chúng xảy ra quá nhanh trước khi thực thi trong luồng chính đến khi Kết thúc Sử dụng.
AlexVB
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.