2013-03-19 38 views
5

tôi bắt đầu hình thức của tôi theo cách thông thường:Cách thích hợp để đóng ứng dụng WinForms theo cách lập trình sau một thời gian nhất định là gì?

Application.Run(new MainForm()); 

Tôi muốn nó để mở và chạy cho đến một thời gian nhất định, sau đó đóng. Tôi đã thử những điều sau đây nhưng không có kết quả:

(1) Trong phương thức Main (là Application.Run() tuyên bố là), tôi nhập dữ liệu sau SAU Application.Run()

while (DateTime.Now < Configs.EndService) { } 

KẾT QUẢ: Nó không bao giờ bị đánh trúng.

(2) TRƯỚC Application.Run() Tôi bắt đầu một nền mới Ðề tài:

 var thread = new Thread(() => EndServiceThread()) { IsBackground = true }; 
     thread.Start(); 

nơi EndServiceThread là:

public static void EndServiceThread() 
    { 
     while (DateTime.Now < Configs.EndService) { } 
     Environment.Exit(0); 
    } 

KẾT QUẢ: vshost32.exe đã ngừng tai nạn lao động.

(3) Trong MainForm Tick sự kiện:

 if (DateTime.Now > Configs.EndService) 
     { 
      this.Close(); 
      //Environment.Exit(0); 
     } 

KẾT QUẢ: vshost32.exe đã ngừng tai nạn lao động.

Cách thích hợp để đạt được mục tiêu của tôi là gì? Một lần nữa, tôi muốn khởi chạy Biểu mẫu, để mở Biểu mẫu & cho đến một thời điểm nhất định (Configs.EndService), sau đó đóng.

Cảm ơn bạn, Ben.

Trả lời

4

Tạo Timer và yêu cầu đóng chương trình trong trình xử lý sự kiện của nó.

Giả sử bạn muốn ứng dụng tắt sau 10 phút. Bạn khởi tạo bộ hẹn giờ với khoảng thời gian 60.000 mili giây. xử lý sự kiện của bạn trở thành:

void TimerTick(object sender) 
{ 
    this.Close(); 
} 

Nếu bạn muốn nó đóng cửa ở mức một ngày và thời gian cụ thể, bạn có thể có bộ đếm thời gian đánh dấu một lần mỗi giây, và kiểm tra DateTime.Now chống lại thời gian kết thúc mong muốn.

Điều này sẽ hiệu quả vì TimerTick sẽ thực thi trên chuỗi giao diện người dùng. Vấn đề với ý tưởng chuỗi riêng biệt của bạn là Form.Close được gọi trên một chuỗi nền, không phải là chuỗi giao diện người dùng. Điều đó ném một ngoại lệ. Khi bạn tương tác với các phần tử giao diện người dùng, nó phải nằm trên chuỗi giao diện người dùng.

Ý tưởng chuỗi nền của bạn có thể hoạt động nếu bạn gọi là Form.Invoke để thực hiện Close.

Bạn cũng có thể tạo đối tượng WaitableTimer và đặt sự kiện của đối tượng đó cho thời gian cụ thể. Khung không có WaitableTimer nhưng có sẵn. Xem bài viết Waitable Timers in .NET with C#. Mã có sẵn tại http://www.mischel.com/pubs/waitabletimer.zip

Nếu bạn sử dụng WaitableTimer, lưu ý rằng lệnh gọi lại thực hiện trên chuỗi nền.Bạn sẽ phải Invoke để đồng bộ hóa với chuỗi giao diện người dùng:

this.Invoke((MethodInvoker) delegate { this.Close(); }); 
+0

đâu bạn sẽ thêm cái này chứ? Trong 'MainForm', vì đó là điểm khởi chạy của các loại cho phần còn lại của ứng dụng? –

+1

@Grant: Có, hãy đặt bộ hẹn giờ trên biểu mẫu chính. Đặt thuộc tính 'Enabled' thành' True', và khoảng thời gian của nó đến bất kỳ khoảng thời gian kiểm tra nào bạn muốn (1 giây, 10 phút, bất cứ điều gì). –

0

Có sự kiện "ServiceEnded" không? Nếu có, hãy đóng biểu mẫu của bạn khi dịch vụ của bạn kết thúc.

+0

Làm thế nào về việc xây dựng cách OP có thể thực hiện điều này? –

+0

người hỏi câu hỏi cần cung cấp thêm một số mã để có câu trả lời tốt hơn. Tôi không nghĩ rằng việc đóng ứng dụng bằng bộ hẹn giờ là tốt. – Dilshod

2

Làm thế nào về một cái gì đó như thế này:

public partial class Form1 : Form 
{ 
    private static Timer _timer = new Timer(); 

    public Form1() 
    { 
     InitializeComponent(); 
     _timer.Tick += _timer_Tick; 
     _timer.Interval = 5000; // 5 seconds 
     _timer.Start();    
    } 

    void _timer_Tick(object sender, EventArgs e) 
    { 
     // Exit the App here .... 
     Application.Exit(); 
    } 
} 
0

Nếu bạn sử dụng System.Threading.Timer bạn có thể sử dụng DueTime để thiết lập lần đầu tiên nó cháy như thời gian bạn muốn đóng ứng dụng của bạn

new System.Threading.Timer((o) => Application.Exit(), null, (Configs.EndService - DateTime.Now), TimeSpan.FromSeconds(0)); 
Application.Run(new Form1()); 
+1

Bạn có chắc chắn rằng nó an toàn để gọi 'Application.Exit' từ một chuỗi nền? Ngoài ra, điều này sẽ thất bại nếu đồng hồ hệ thống thay đổi (Thay đổi giờ tiết kiệm ánh sáng ban ngày), trong khi chương trình đang chạy. –

+0

Application.Exit có vẻ là tốt trên một chủ đề nền (Tôi đã thử nghiệm này trước khi gửi bài), Thời gian đóng được xác định khi bộ đếm thời gian được tạo nên việc thay đổi đồng hồ sẽ không thay đổi thời gian Bộ hẹn giờ kích hoạt –

+0

"Thời gian đóng được xác định khi hẹn giờ được tạo. " Điều đó không đúng chút nào. * Lượng thời gian chờ * được xác định tại thời điểm tạo. Nếu bạn bắt đầu chương trình lúc nửa đêm và muốn đóng chương trình lúc 4:00 sáng, điều này sẽ chờ 4 giờ. Nhưng vào ngày "mùa xuân sắp tới", sẽ là 5:00 sáng trước khi hẹn giờ được đánh dấu. Và vào ngày "rơi trở lại", bộ hẹn giờ sẽ đánh dấu vào lúc 3:00 sáng. Nếu đồng hồ hệ thống thay đổi, bất kỳ khoảng thời gian nào dựa trên giá trị trước đó đều không hợp lệ. –

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