2009-02-08 21 views
11

Làm cách nào để phát hiện ứng dụng .NET của tôi đã bị lỗi, sau đó khởi động lại?Phát hiện và khởi động lại ứng dụng .NET bị lỗi của tôi

+0

Tôi đã tìm thấy một số giải pháp cho câu hỏi này (trước khi tôi hỏi nó), vì vậy tôi nghĩ sẽ tốt hơn nếu có câu trả lời trong SO. Nếu bạn có thêm câu trả lời, hãy làm khách của tôi. Hoặc chỉ bỏ phiếu cho câu trả lời hay nhất để hướng dẫn người khác. Ngoài ra, vui lòng trả lời câu hỏi này khi bạn cho là phù hợp. –

+0

Đã thêm thông tin về cách khởi động lại ứng dụng bảng điều khiển vì đây rõ ràng là những gì bạn đang sử dụng. – RoadWarrior

Trả lời

14

Một giải pháp (dựa trên this example) là để tạo ra một launcher điều khiển ứng dụng:

class LauncherProgram 
{ 
    static int count = 3; 

    static void Main() 
    { 
     Launch(); 
     Thread.Sleep(Timeout.Infinite); 
    } 

    static void Launch() 
    { 
     Process process = new Process(); 
     process.StartInfo.FileName = "MyApp.exe"; 
     process.EnableRaisingEvents = true; 
     process.Exited += LaunchIfCrashed; 
    } 

    static void LaunchIfCrashed(object o, EventArgs e) 
    { 
     Process process = (Process) o; 
     if (process.ExitCode != 0) 
     { 
      if (count-- > 0) // restart at max count times 
       Launch(); 
      else 
       Environment.Exit(process.ExitCode); 
     } 
     else 
     { 
      Environment.Exit(0); 
     } 
    } 
+1

Việc nâng cấp duy nhất có thể là làm cho "cơ quan giám sát" trở thành dịch vụ cửa sổ. –

+0

tốt hơn để thêm một số mã dấu thời gian và phát hiện xem ứng dụng có bị lỗi khi khởi động – Sean

1

Một giải pháp khả thi là tạo ra một tiến trình khác để giám sát ứng dụng của bạn, và khởi động lại nó nếu nó bị chấm dứt:

class ProcessMonitorProgram 
{ 
    const string myProcess = "MyApp.exe"; 

    static void Main() 
    { 
     new Timer(CheckProcess, null, 0, 60 * 1000); 
     Thread.Sleep(Timeout.Infinite); 
    } 

    static void CheckProcess(object obj) 
    { 
     if (Process.GetProcessesByName(myProcess).Length == 0) 
      Process.Start(myProcess); 
    } 
} 

Một trong những vấn đề với giải pháp này là nó sẽ tiếp tục quá trình khởi động lại mãi mãi, cho đến khi bản thân ứng dụng giám sát này được chấm dứt.

5
  • chạy các công việc bên trong một AppDomain; sử dụng AppDomain chính để giám sát nó (mặc dù không bảo vệ chống lại quá trình giết), tuy nhiên,
  • xử lý ngoại lệ! tức là đừng để một lỗi nghiêm trọng phá đổ quá trình
  • chạy nó trong một cái gì đó đã có tái chế xây dựng trong - IIS ví dụ
+1

Cảm ơn Marc. Bạn có thể vui lòng thêm một ví dụ về cách triển khai giải pháp dựa trên AppDomain mà bạn đề xuất không? –

+0

Giả sử đây là ứng dụng Windows Forms hoặc giao diện điều khiển, bạn có thể sử dụng Application.Restart - xem câu trả lời của tôi để biết chi tiết. – RoadWarrior

8

Nếu đây là một ứng dụng Windows Forms:

  • Set jitDebugging = true trong App.Config. Điều này ngăn cản việc xây dựng trong Windows Forms xử lý ngoại lệ unhandled được kích hoạt.

Bây giờ bất kể này là một ứng dụng Windows Forms hoặc một ứng dụng giao diện điều khiển:

  • Đăng ký cho kiện Application.ThreadException, ví dụ trong C#:

    Application.ThreadException + = new Threading.ThreadExceptionHandler (CatchFatalException);

Tại thời điểm này, ứng dụng của bạn đang trên đường vào lỗ đen. Chuyện gì xảy ra tiếp theo phụ thuộc vào việc hay không đây là một ứng dụng Windows Forms:

  • Nếu đó là một ứng dụng Windows Forms, gọi phương thức Application.Restart trong xử lý sự kiện CatchFatalException của bạn.
  • Nếu không, bạn sẽ cần p/gọi tới application restart and recovery các hàm gốc. Liên kết đó thảo luận về Vista, nhưng trong các thử nghiệm của tôi, nó cũng hoạt động tốt trên XP.
+0

Cảm ơn bạn. Có thể cho một ứng dụng bàn điều khiển để làm một cái gì đó tương tự như 'Application.ThreadException + = MyHandler;'? –

+0

Có, ứng dụng bảng điều khiển có thể thực hiện tương tự. – RoadWarrior

+0

Nhưng nó không có quyền truy cập vào lớp Ứng dụng, phải không? –

Các vấn đề liên quan