2012-11-10 44 views
6

Tôi đang chơi một chút với một số mã C# Winforms/WPF và chỉ tình cờ gặp phải điều gì đó kỳ lạ. Hãy nói rằng tôi có một mã như thế này:Dừng thực thi mã C#

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     DoSomething(); 

     // maybe something more if everything went ok 
    } 
} 

gì tôi bối rối là tôi không thể chỉ đơn giản là đóng ứng dụng từ phương pháp DoSomething trước khi xây dựng xong công việc của mình. Nếu bất cứ điều gì trong quá trình thực hiện DoSomething không thành công, tôi cần phải đóng ứng dụng ngay lập tức, nhưng nó chỉ tiếp tục chạy, thực hiện phần // maybe something more... và THEN đóng, nhưng đó là cách quá muộn đối với tôi.

Tôi phải đặt mã để đóng biểu mẫu bên trong hàm tạo bằng cách sau return; và sau đó nó hoạt động, nhưng tôi không thực sự thấy rằng một giải pháp có thể chấp nhận được. Tôi đang cố gắng để di chuyển logic xác nhận như vậy từ các nhà xây dựng để phương pháp của tôi.

tôi đã cố gắng những thứ như

public void DoSomething() 
{ 
    Close(); 
} 

hoặc

public void DoSomething() 
{ 
    Application.Current.Shutdown(); 
} 

Nhưng nó dường như không làm việc. Có, cả hai mã đều đóng ứng dụng, nhưng chỉ sau khi mã xây dựng hoàn thành hoàn chỉnh.

Why tôi có cần một thứ như vậy không? Vâng, bởi vì lúc khởi động, tôi cần phải kiểm tra những thứ khác nhau, như sự sẵn có của kết nối và phần cứng, xác thực người dùng, và nếu bất cứ điều gì không thành công, không có điểm thực thi mã nữa.

Đã thử nguyên tắc tương tự với Winforms và WPF (do đó các thẻ), hoạt động tương tự.

Ai cũng có thể giải thích hoặc có thể là giải pháp? Tôi biết điều này có lẽ rất cơ bản đối với một số bạn, nhưng xin vui lòng, với tôi, tôi không phải là một lập trình viên Windows, vì vậy đây là điều mới mẻ đối với tôi. Các trang web làm việc một chút khác nhau ... :)

+0

Khi biểu mẫu đầu tiên đang được tạo, không có ứng dụng nào đang chạy, vì vậy Shutdown() có thể bị bỏ qua. Avip cung cấp giải pháp tốt. –

Trả lời

8

Chỉ cần thử sử dụng Environment.Exit(-1) trong trường hợp của bạn và tất cả sẽ tốt.

ADDED:Đây là tài liệu tham khảo tốt nhất mà tôi có thể nhận được cho bạn.

Sự khác nhau giữa Application.Exit vs Application.Shutdown vs Environment.Exit

Application.Exit() là cho thoát một ứng dụng hình thức cửa sổ một cách duyên dáng. Về cơ bản, nó dừng bơm thông điệp, đóng tất cả các cửa sổ và đưa bạn trở lại phương thức Main() ngay sau khi gọi đến Application.Run().Tuy nhiên, đôi khi nó không xuất hiện để làm việc - điều này thường là bởi vì có những chủ đề tiền cảnh khác (ngoài các chủ đề giao diện người dùng) vẫn chạy mà đang ngăn chặn các chủ đề từ kết thúc.

Application.Shutdown() là (rộng rãi) tương đương với Application.Exit() trong ứng dụng WPF. Tuy nhiên, bạn có thể kiểm soát nhiều hơn một chút vì bạn có thể đặt ShutDownMode để ứng dụng tắt khi cửa sổ chính đóng, cửa sổ cuối cùng đóng hoặc chỉ khi phương thức này được gọi.

Environment.Exit() giết tất cả các chủ đề đang chạy và quá trình tự đá chết. Điều này chỉ nên được sử dụng trong WF hoặc WPF như là phương sách cuối cùng khi các phương thức duyên dáng hơn không hoạt động vì một lý do nào đó. Nó cũng có thể được sử dụng để thoát khỏi một ứng dụng console.

Một tham khảo: How to properly exit a C# application?

+0

Cảm ơn, điều này dường như hoạt động như mong đợi. Bạn có thể giải thích, tại sao nó không hoạt động với 'Shutdown()' hay 'Close()'? Có bất kỳ cạm bẫy nào để tìm kiếm giải pháp của bạn không? – walther

+0

Không có cạm bẫy. Thay vào đó, trách nhiệm cốt lõi của Environment.Exit là chấm dứt quá trình và cung cấp cho hệ điều hành cơ bản mã thoát được chỉ định. Tham khảo: http://msdn.microsoft.com/en-us/library/system.environment.exit.aspx –

+0

Cảm ơn bạn. Có những lần tôi không cần phải ném ngoại lệ vv, chỉ đơn giản là "bỏ thuốc lá". :) – walther

0

Một cách giải quyết sẽ được ném một ngoại lệ và xử lý nó trong application.UnhandledException

3

Bạn luôn có thể bỏ qua các nhà phát triển đồng bào của bạn và chỉ sử dụng Environment.FailFast()

Nhưng thực sự - don 't. Nếu bạn có những điều quan trọng cần làm, S.A xác minh cổng nối tiếp được kết nối với nhà máy điện hạt nhân, chỉ cần làm điều đó trước. Không có quy tắc nào buộc bạn phải Application.Run(...) ngay sau khi gọi Main().

+0

Bạn có thể vui lòng giải thích, tại sao không làm điều đó? Các giải pháp từ FSX dường như làm việc, có bất kỳ vấn đề tiềm năng để nhận thức được với cách tiếp cận của mình? 'Application.Run' chỉ liên quan đến Winforms (hoặc có lẽ tôi sai?), Nhưng còn WPF thì sao?Xin vui lòng, bạn có thể hiển thị một ví dụ trong WPF để minh họa cho giải pháp của bạn, ví dụ: nơi bạn sẽ đặt các hướng dẫn khởi động quan trọng (kiểm tra cho các cổng mở và các công cụ như thế)? Ví dụ đơn giản sẽ làm. – walther

0

Xác định một lớp ngoại lệ:

public class InitializationException : Exception 
{ 
    public InitializationException() 
    {} 

    public InitializationException(string msg) 
     : base(msg) 
    {} 

    public InitializationException(string msg, Exception inner) 
     : base(msg, inner) 
    {} 
} 

và thay đổi mã của bạn như thế này:

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     try 
     { 
      DoSomething(); 

      // maybe something more if everything went ok 
     } 
     catch(InitializationException ex) 
     { 
      // log the exception 
      Close(); 
     } 
    } 

    public void DoSomething() 
    { 
     if (notSomethingOK) 
      throw new InitializationException("Something is not OK and the applicaiton must shutdown."); 
    } 
} 

Đây là một giải pháp làm sạch và duy trì.

1

Đã có đăng các giải pháp khả thi cho sự cố của bạn.

Chỉ để trả lời câu hỏi tiếp theo: lý do tại sao các phương thức như Close() và Shutdown() không thoát khỏi ứng dụng của bạn ngay cả khi chỉ cần đẩy tin nhắn vào hàng đợi tin nhắn của ứng dụng. Chúng chỉ được xử lý sau khi hàm tạo của MainWindow hoàn thành và thực thi mã trả về vòng lặp xử lý tin nhắn, thậm chí sau khi một số tin nhắn khác đang chờ xử lý trong hàng đợi cũng đã được xử lý. Ngược lại, các phương thức như Environment.Exit() hoặc Environment.FailFast() là các hàm os lõi cứng dẫn đến nhiều hoặc ít ngay lập tức giết chết quá trình.

+0

Cảm ơn bạn đã giải thích. Xấu hổ tôi không thể chọn nhiều câu trả lời. Ít nhất +1 cho bạn quá :) – walther

0
System.Windows.Forms.Application.Exit(); 
0

Những điều như vậy khái niệm không nên được sử dụng trong các nhà xây dựng lớp học. Constructor phần nào được tạo ra để khởi tạo ví dụ với trạng thái bắt đầu và không phải những điều thực tế có thể xảy ra (như trường hợp ngoại lệ, hộp thông báo, v.v.).

Đừng quên rằng bạn chỉ có thể trả lại ; từ hàm tạo, nếu bạn cần phá vỡ thực thi của nó. Đây là chiến thuật tốt hơn (hầu hết thời gian bạn không cần phải tắt ứng dụng do lỗi mà không hiển thị một số văn bản).

Có "cửa sổ hiển thị", "hiển thị thay đổi", "đã tải" và nhiều sự kiện khác trong C# trên Windows/WPF, bạn có thể ghi đè hầu như hoặc thêm làm trình xử lý sự kiện. Khởi tạo biểu mẫu/ứng dụng của bạn ở đó.

Đó là các phương pháp bình thường nên tất cả đều hoạt động như mong đợi. Bạn có thể thử ném ngoại lệ rằng điểm vào ứng dụng của bạn (Chức năng chính) sẽ chỉ bắt và bỏ qua.

Đối với WPF, hãy kiểm tra điều này: - https://msdn.microsoft.com/en-us/library/system.windows.forms.application.setunhandledexceptionmode(v=vs.110).aspx.

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