2013-02-15 33 views
17

Tôi sử dụng một chuỗi viết trong một lớp khác để cập nhật nhãn. Nhãn là nội dung trong lớp Chính Winform.Cập nhật nhãn từ một chủ đề khác

Scanner scanner = new Scanner(ref lblCont); 
scanner.ListaFile = this.listFiles; 
Thread trd = new Thread(new ThreadStart(scanner.automaticScanner)); 
trd.IsBackground = true; 
trd.Start(); 
while (!trd.IsAlive) ; 
trd.Join(); 

Làm thế nào bạn có thể thấy, tôi chuyển tham chiếu nhãn vào hàm tạo của lớp thứ hai. Trong lớp thứ hai (Scanner) tôi đã một phương pháp gọi là "automaticScanner" mà nên cập nhật nhãn với mã này:

public Scanner(ref ToolStripStatusLabel _lblContatore) 
{ 
     lblCounter= _lblContatore; 
} 
Thread threadUpdateCounter = new Thread(new ThreadStart(this.UpdateCounter)); 
threadUpdateCounter.IsBackground = true; 
threadUpdateCounter.Start(); 
while (!threadUpdateCounter .IsAlive) ; 
threadUpdateCounter.Join(); 

private void AggiornaContatore() 
{ 
    this.lblCounter.Text = this.index.ToString();   
} 

Tôi đã nhận lỗi này trên bản cập nhật của nhãn:

Hoạt động của chuỗi chéo không hợp lệ: Kiểm soát 'Chính' được truy cập từ một chuỗi khác với chuỗi được tạo trên

Tôi sử dụng .net 4 với Winform C#.

Cảm ơn rất nhiều câu trả lời.

Tin tức: Vấn đề là dòng này:

trd.Join(); 

Dòng này chặn GUI của tôi và lable không được cập nhật. Có các phương pháp để kiểm soát kết thúc của chuỗi và cập nhật nhãn cho đến khi kết thúc? Cảm ơn

+0

nhưng ... cuộc gọi chính xác của nó thread trong chế độ này? Thread trd = new Thread (ThreadStart mới (scanner.scansioneAutomatica)); trd.IsBackground = true; trd.Start(); khi (! Trd.IsAlive); trd.Join(); Trong chế độ này, GUI bị chặn! : S – Antonio

+0

Bao gồm bên trong lớp mã Action y; và chức năng để tham dự các sự kiện thời gian trôi qua tư nhân void T_Elapsed (đối tượng người gửi, System.Timers.ElapsedEventArgs e) { C++; // đại biểu là biểu thức "y =() => label1.Text = c.ToString()" label1.Invoke (y =() => label1.Văn bản = c.ToString()); } –

Trả lời

41

Bạn không thể cập nhật giao diện người dùng từ bất kỳ chủ đề nào khác ngoài chuỗi giao diện người dùng. Sử dụng tính năng này để cập nhật chuỗi trên chuỗi giao diện người dùng.

private void AggiornaContatore() 
{   
    if(this.lblCounter.InvokeRequired) 
    { 
     this.lblCounter.BeginInvoke((MethodInvoker) delegate() {this.lblCounter.Text = this.index.ToString(); ;});  
    } 
    else 
    { 
     this.lblCounter.Text = this.index.ToString(); ; 
    } 
} 

Hãy đi qua chương này và nhiều hơn nữa từ cuốn sách này để có được một bức tranh rõ ràng về luồng:

http://www.albahari.com/threading/part2.aspx#_Rich_Client_Applications

+0

lblCounter không chứa định nghĩa cho InvokeRequired, tương tự cho BeginInvoke – Antonio

+0

tôi không có Nhãn, nhưng ToolStripStatusLabel – Antonio

+0

IIRC, InvokeRequired tồn tại trong mọi điều khiển, nhưng được bảo vệ, đây là lý do tại sao bạn chỉ thấy nó trong " lớp hiện tại của bạn "(ví dụ: Form, UserControl) và cố gắng truy cập nó trên một lớp khác (ví dụ: Label, TextBox) không thành công – quetzalcoatl

10

Sử dụng MethodInvoker để cập nhật văn bản nhãn trong chuỗi khác.

private void AggiornaContatore() 
{ 
    MethodInvoker inv = delegate 
    { 
     this.lblCounter.Text = this.index.ToString(); 
    } 

this.Invoke(inv); 
} 

Bạn nhận được lỗi vì chuỗi giao diện người dùng đang giữ nhãn và vì bạn đang cố gắng cập nhật nó qua một chuỗi khác, bạn nhận được ngoại lệ chéo.

Bạn cũng có thể thấy: Threading in Windows Forms

+0

lớp học của tôi không giao diện IDisposable. vì lý do này this.IsDisposed không được tìm thấy .. – Antonio

+0

@Antonio, loại bỏ các kiểm tra và chỉ cần gọi nó trực tiếp – Habib

+0

trong phương pháp Aggiorna contatore của lớp học của tôi Máy quét phương pháp Gọi không tìm thấy. – Antonio

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