2011-12-16 29 views
5

Tôi có bộ đếm thời gian được đặt trong 10 giây tại một trong các hình thức cửa sổ của tôi. Và đối với OnTimedEvent, tôi đặt cho biểu mẫu được xử lý sau thời gian đã hết. Tuy nhiên, có vẻ như có lỗi củaLỗi Cross Thread xử lý biểu mẫu với Timer

InvalidOperationException bị unhandled bởi mã người dùng.

Hoạt động trên luồng không hợp lệ: Kiểm soát 'thông báo' Truy cập 'được truy cập từ một chuỗi khác với chuỗi được tạo trên đó.

Các lỗi được trên dòng

protected override void Dispose(bool disposing) 
    { 
     if (disposing && (components != null)) 
     { 
      components.Dispose(); 
     } 
     base.Dispose(disposing); 
    } 

mã cho sự kiện timer của tôi là

private void OnTimedEvent(object source, ElapsedEventArgs e) 
    { 
     this.Dispose(); 
    } 

Bất cứ ai cũng biết làm thế nào để sửa lỗi này? cảm ơn!

Trả lời

4

Có vẻ như bạn đang sử dụng System.Timers.Timer.

Hãy thử sử dụng số System.Windows.Forms.Timer thay thế và đăng ký sự kiện Tick.

Nếu bạn phải sử dụng Timer đó, bạn có thể thử thay đổi mã của bạn như thế này:

private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    this.BeginInvoke((MethodInvoker)delegate { this.Dispose(); }); 
} 
+0

hi. cảm ơn bạn đã trả lời. chỉ cần biết, sự khác biệt giữa system.windows.form.timer so với bộ đếm thời gian bình thường là gì? – Thomas

+1

Timers.Timer là bộ đếm thời gian dựa trên máy chủ, đó là lý do tại sao nó nằm trên một chuỗi khác với biểu mẫu của bạn. Bộ đếm thời gian của windows chạy trên cùng một luồng với GUI - đó là lý do tại sao cho một ứng dụng winforms, nó thường là bộ đếm thời gian thích hợp hơn để sử dụng. Bộ đếm thời gian trong ToolBox là Forms.Timer. – LarsTech

1

Hoặc chỉ:

this.Invoke((Action)(() => { this.Dispose(); })); 

Bạn có thể làm điều này trong một dòng:

timer1.Tick += (_, __) => { this.Invoke((Action)(() => { this.Dispose(); })); }; 
1

Như những người khác đã nêu, vấn đề là bộ đếm thời gian của bạn đang chạy một sợi và cố gắng vứt bỏ một đối tượng là cr ăn trên sợi khác. Bạn cần phương thức vứt bỏ để gọi trên biểu mẫu trước khi nó cố gắng truy cập nó.

Điều cơ bản cần lưu ý, nếu bạn cố gắng thay đổi đối tượng trình bày được tạo trong trình thiết kế từ một chuỗi khác, bạn cần kiểm tra xem có yêu cầu gọi hay không.

void OnTick() 
{ 
    if (InvokeRequired) 
     Invoke(new MethodInvoker(OnTick)); 
    else 
    { 
     Dispose(); 
    } 
} 
2
private void OnTimedEvent(object source, ElapsedEventArgs e) 
{ 
    this.Invoke(new Action(() => this.Dispose())); 
} 

này hoạt động vì nó là