2010-02-10 37 views
11

Tôi đang sử dụng vb.net, và trong chương trình của mình, tôi nhận được lỗi 'hoạt động chéo không hợp lệ' này khi tôi chạy backgroundworker của mình. Tiểu ban đầu tiên của tôi sẽ bật tính năng được bật thành false và khi nhân viên nền chạy nó sẽ biến nó thành sự thật rồi thoát ra. Tại sao nó cho tôi một lỗi? FYI: Có nhiều mã để này nhưng tôi không muốn làm cho nó bất kỳ khó hiểu hơn ...Hoạt động Crossthread không hợp lệ ... - VB.NET

Đây là stack trace:

at System.Windows.Forms.Control.get_Handle() 
    at System.Windows.Forms.Control.OnEnabledChanged(EventArgs e) 
    at System.Windows.Forms.Control.set_Enabled(Boolean value) 
    at Helium.Form1.BackgroundWorker1_DoWork(Object sender, DoWorkEventArgs e) in C:\Users\Kevin\documents\visual studio 2010\Projects\Helium\Helium\Form1.vb:line 167 
    at System.ComponentModel.BackgroundWorker.OnDoWork(DoWorkEventArgs e) 
    at System.ComponentModel.BackgroundWorker.WorkerThreadStart(Object argument) 

và đây là thông báo lỗi chính xác:

{"Cross-thread operation not valid: Control 'mainText' accessed from a thread other than the thread it was created on."} 

Ai đó có thể vui lòng giúp tôi!

Cảm ơn,

Kevin

+0

Tôi nghĩ rằng các thông báo lỗi là khá tự giải thích. –

Trả lời

16

Mục đích của lớp BackgroundWorker là thực hiện công việc trên luồng không phải GUI trong khi GUI vẫn đáp ứng. Trừ khi bạn đặt Control.CheckForIllegalCrossThreadCalls thành false (bạn không nên làm), hoặc sử dụng Invoke như được đề xuất trong các câu trả lời khác (mà tôi cũng sẽ không khuyên bạn), bạn sẽ nhận được một ngoại lệ hoạt động chéo bất hợp pháp.

Nếu bạn muốn giao diện liên quan đến "công cụ" để xảy ra khi bạn BackgroundWorker đang chạy, tôi muốn thường khuyên bạn nên sử dụng phương pháp BackgroundWorker.ReportProgress và gắn một handler phù hợp với sự kiện BackgroundWorker.ProgressChanged. Nếu bạn muốn một cái gì đó trên GUI xảy ra khi BackgroundWorkerhoàn thành, sau đó chỉ cần đính kèm trình xử lý của bạn để cập nhật GUI lên sự kiện BackgroundWorker.RunWorkerCompleted.

+0

+1. Sử dụng 'backgroundworker.reportprogress' đã giúp tôi cập nhật gui của tôi trong khi chuỗi đang chạy. – Codemunkeee

2

Bạn không thể trực tiếp đặt thuộc tính của điều khiển mà là trên thread UI từ thread khác. Nó có thể được thực hiện mặc dù, đây là một ví dụ từ msdn.

Private Sub SetText(ByVal [text] As String) 

    ' InvokeRequired required compares the thread ID of the' 
    ' calling thread to the thread ID of the creating thread.' 
    ' If these threads are different, it returns true.' 
    If Me.textBox1.InvokeRequired Then 
     Dim d As New SetTextCallback(AddressOf SetText) 
     Me.Invoke(d, New Object() {[text]}) 
    Else 
     Me.textBox1.Text = [text] 
    End If 
End Sub 
+0

vì vậy tôi nên đặt textbox1.enabled = true part? – lab12

10

Bạn đặt chính xác thuộc tính Enabled ở đâu? Nếu bạn làm điều đó trong trình xử lý sự kiện DoWork, mã này đang chạy trên một chuỗi khác với nút được tạo, điều này sẽ cung cấp cho ngoại lệ mà bạn gặp phải. Để giải quyết vấn đề này, bạn nên sử dụng BeginInvoke. Để thuận tiện nó có thể được gói gọn trong một phương pháp, như vậy:

Private Sub SetControlEnabled(ByVal ctl As Control, ByVal enabled As Boolean) 
    If ctl.InvokeRequired Then 
     ctl.BeginInvoke(New Action(Of Control, Boolean)(AddressOf SetControlEnabled), ctl, enabled) 
    Else 
     ctl.Enabled = enabled 
    End If 
End Sub 

Bây giờ bạn có thể yên tâm gọi là phương pháp để kích hoạt hoặc vô hiệu hóa bất kỳ kiểm soát từ bất kỳ chủ đề:

SetControlEnabled(someButton, False) 
2

Form_Load() của bạn, hãy viết phần mã bên dưới. Tất cả các vấn đề của bạn sẽ được giải quyết.

'## crossed-thread parts will not be controlled by this option... 

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False 
11

Loại mã sau trong Form1_Load (hoặc bất kỳ hình thức của bạn là) phụ:

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False 

Nó sửa chữa tất cả các vấn đề với chặn hoạt động chéo sợi.

+0

Lưu ý rằng câu trả lời này là * xấu *, như được giải thích trong [Có an toàn để đặt CheckForIllegalCrossThreadCalls thành sai để tránh lỗi luồng chéo trong khi gỡ lỗi không?] (Http://stackoverflow.com/questions/13345091/is-it-safe -just-to-set-checkforillegalcrossthreadcalls-to-false-to-tránh-cross-t). ** Xin vui lòng không sử dụng nó và thay vào đó sửa chữa các vấn đề với mã của bạn (tức là, tạo đại biểu thích hợp). ** – cybermonkey

5

Cách tốt hơn để làm điều này trong VB.NET là sử dụng Extension nó làm cho mã tìm kiếm rất đẹp cho các cuộc gọi điều khiển GUI qua luồng.

Chỉ cần thêm dòng mã này vào bất kỳ Mô-đun nào bạn có.

<System.Runtime.CompilerServices.Extension()> _ 
Public Sub Invoke(ByVal control As Control, ByVal action As Action) 
    If control.InvokeRequired Then 
     control.Invoke(New MethodInvoker(Sub() action()), Nothing) 
    Else 
     action.Invoke() 
    End If 
End Sub 

Bây giờ bạn có thể viết mã Kiểm soát chéo chỉ dài 1 dòng cho bất kỳ cuộc gọi điều khiển nào.

Như thế này, cho phép nói rằng bạn muốn xóa một ComboBox và nó được gọi là từ chủ đề hoặc không có chủ đề bạn chỉ có thể sử dụng làm này ngay bây giờ

cboServerList.Invoke(Sub() cboServerList.Items.Clear()) 

Bạn muốn thêm một cái gì đó sau khi bạn rõ ràng nó?

cboServerList.Invoke(Sub() cboServerList.Items.Add("Hello World")) 
0

Đề xuất sử dụng AutomationPeer.

Ví dụ bên dưới các cuộc gọi mã Thực hiện nút khi tôi nhấn phím F5. Tương tự như vậy nếu bạn muốn một chủ đề hoặc nhân viên nền để gọi một sự kiện hoặc chức năng bạn có thể sử dụng tự động hóa Peer. Trong trường hợp của bạn thay vì nút (mà tôi đã sử dụng ở đây), bạn có thể sử dụng hộp văn bản với thuộc tính thích hợp của nó để gọi.

'Button name=btnExecute 

'Imports System.Windows.Automation.Peers 

'Imports System.Windows.Automation.Provider 

If e.Key = Key.F5 Then 

    Dim peer As New ButtonAutomationPeer(btnExecute) 

    Dim invokeProv As IInvokeProvider = TryCast(peer.GetPattern(PatternInterface.Invoke), IInvokeProvider) 

    invokeProv.Invoke() 

End If 

Trân RV

0
CheckForIllegalCrossThreadCalls = False 
+0

Vui lòng thêm một số giải thích bổ sung. – rghome

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