2012-10-03 24 views
5

Tôi đang sử dụng C# với Compact Framework 2, SP2.System.Threading.Timer Not Starting?

Hệ điều hành của thiết bị được thiết lập để khởi động ứng dụng của tôi, hãy gọi ứng dụng "Loader.exe".

Trình tải chỉ đơn giản là: một biểu mẫu đơn, đơn giản hiển thị thông báo trạng thái trong suốt quá trình tải, nếu cần thiết (các thuật ngữ của layman có lỗi và thông báo ngoại lệ hoặc "ứng dụng bắt đầu [xyz]") và máy trạng thái chạy ở chế độ nền trong khi biểu mẫu toàn màn hình cơ bản được hiển thị.

Vì vậy, xây dựng hình thức của Loader vừa thể hiện sau vào rất cuối:

try 
{ 
    label1.Text = "Starting GUI Init Thread..."; //debug only message 
    System.Threading.Timer guiInit = new System.Threading.Timer(
     RunStateMachine, null, 2000, System.Threading.Timeout.Infinite 
     ); 
    //callback: RunStateMachine, null argument 
    //initial callback is 2000ms from this point, and doesn't run again. 
} 
catch (Exception ex1) 
{ 
    label1.Text = "GUI Init Error 2"; 
    Failure_Label.Text = ex1.Message; 
} 

Và "RunStateMachine" làm việc trên một sợi khác với giao diện người dùng, cho phép hình thức để hiển thị, và bất cứ lúc nào nhu cầu RunStateMachine để tương tác với biểu mẫu, chẳng hạn như cập nhật thư, tôi gọi một hàm sử dụng if (this.InvokeRequired) {this.Invoke (...);} else {...}

Vì vậy, vấn đề của tôi?
Không liên tục, chương trình của tôi sẽ bị treo và do bộ hẹn giờ không kích hoạt gọi lại. Tôi đã thêm vào thông báo gỡ lỗi trong khối thử ở trên, cùng với nhiều địa điểm khác để cho tôi biết nơi nó bị treo lên, bao gồm một thông báo tại VERY bắt đầu của "RunStateMachine". Cuối cùng, chương trình của tôi được treo trên thông báo "Bắt đầu GUI Init Chủ đề ..."

Điều này cho tôi biết rằng bộ hẹn giờ chỉ không chạy một thời gian.
Lý thuyết của tôi là nó được thu thập rác trước khi bộ hẹn giờ kích hoạt gọi lại. Điều đó có nghĩa là nếu bộ đếm thời gian là toàn cầu, và sau đó xử lý một cách rõ ràng khi tôi chạy đến RunStateMachine, nó sẽ chạy hoàn hảo ... nhưng tôi không muốn nghĩ rằng tôi đã giải quyết nó chỉ để tìm thấy điều này sắp xảy ra một tháng kể từ bây giờ.

Suy nghĩ?

+0

"Treo trên thư" có nghĩa là gì? Không giống như tuyên bố mà bất cứ điều gì có thể gặp khó khăn. –

+0

Không gỡ lỗi với nhãn. Tìm System.Diagnostics.Debug.Print() và thu thập thêm thông tin. –

+0

@ Henk Holterman, thuật ngữ là không chính xác, sau đó. "Chương trình dừng lại vì nó không chạy bất cứ điều gì khác, không phải vì bất cứ điều gì đang chặn." Tôi cảm thấy "treo" sẽ ngắn gọn hơn, mặc dù tôi hiểu nó có một ý nghĩa khác với nó. Khi sử dụng Debug.In thay vì nhãn: nói chung tôi đồng ý, mặc dù kể từ khi tôi không biết trước thời điểm này, ứng dụng đã dừng * hoặc * nếu tôi có quyền truy cập vào nội dung đã được in sau khi dừng, tôi cần một thứ được cập nhật trên màn hình. Cảm ơn bạn cho tip, mặc dù. –

Trả lời

6

Lý thuyết của tôi là nó được thu thập rác trước khi hẹn giờ kích hoạt gọi lại. Điều đó có nghĩa là nếu bộ đếm thời gian là toàn cầu, và sau đó được xử lý một cách rõ ràng khi tôi đến RunStateMachine, nó sẽ chạy hoàn hảo ... nhưng tôi không muốn nghĩ rằng tôi đã giải quyết nó chỉ để tìm điều này sắp xảy ra một tháng từ giờ.

Có vẻ như bạn muốn xác nhận rằng đây là vấn đề của bạn. Vâng, đây là vấn đề.

Bộ hẹn giờ được lưu trữ trong biến cục bộ không bao giờ được sử dụng nữa. Điều này làm cho nó đủ điều kiện cho GC. GC'ing của Timer dẫn đến việc hoàn tất dẫn đến bộ hẹn giờ bị tắt.

Tôi đề nghị bạn lưu bộ hẹn giờ trong trường thể hiện của lớp biểu mẫu và xóa nó khỏi đó khi cuộc gọi lại đã kích hoạt.