2010-02-10 35 views
11

vb.net'i kullanıyorum ve programımda bu 'crossthread işlemi geçerli değil' hatası alıyorum. Benim ana altım ilk olarak false olarak etkinleştirilecek ve arka plan çalışması çalıştığında geri dönecektir. Neden bana bir hata veriyor? Bilginize: Tam bir hata iletisi olup buradaCrossthread işlemi geçerli değil ... - VB.NET

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) 

ve: bununla daha fazla kod yoktur ama burada

yığın izlemesi ... Bundan daha kafa karıştırıcı yapmak istemiyoruz

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

Birisi bana yardım edebilir mi!

sayesinde

KEvin doğrudan başka bir iş parçacığı UI iş parçacığı üzerinde bir denetimin özelliğini ayarlayamıyor

+0

ben hata mesajı yeterince açıklayıcı olduğunu düşünürdüm. –

cevap

16

BackgroundWorker sınıfın amacı GUI yanıt verirken GUI olmayan iş parçacığı üzerinde iş gerçekleştirmektir. Control.CheckForIllegalCrossThreadCalls'u false olarak ayarlamamışsanız (ki bunu yapmamalısınız) ya da diğer yanıtlarda önerildiği gibi Invoke kullanın (bu da benim önerimden başka bir şey değildir), bir çapraz iş parçacıklı işlem istisnası elde edersiniz.

GUI ilgili "şeyler" sizin çalıştıran BackgroundWorker ise gerçekleşmesini istiyorsanız, ben genelde BackgroundWorker.ReportProgress yöntemi kullanarak ve BackgroundWorker.ProgressChanged olaya uygun bir işleyici takılarak öneriyoruz. GUI'de BackgroundWorker bittikten sonra bir şey olmasını istiyorsanız, GUI'yi BackgroundWorker.RunWorkerCompleted olayına güncellemek için işleyicinizi ekleyin.

+0

+1. 'Backgroundworker.reportprogress' kullanma iplik kaçak iken benim GUI güncellenmesinde bana yardımcı oldu. açıklandığı gibi bu yanıt * kötü * olduğunu – Codemunkeee

2

. Yine de yapılabilir, burada msdn'den bir örnek.

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

yüzden nerede textbox1.enabled = true parçası koymak gerekir? – lab12

10

Enabled özelliğinin tam olarak nerede ayarlanır? Bunu, DoWork olay işleyicisinde gerçekleştirirseniz, bu kod, üzerinde oluşturulmuş olandan farklı bir iş parçacığı üzerinde çalışmaktadır, bu da karşılaştığınız istisnayı vermelidir. Bunu aşmak için BeginInvoke kullanmalısınız. kolaylık sağlamak için o kadar gibi bir yöntem haline sarılmış olabilir:

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 

Şimdi güvenle etkinleştirmek veya herhangi iplikten herhangi bir kontrol devre dışı bırakmak için bu yöntemi çağırabilirsiniz:

SetControlEnabled(someButton, False) 
2

Form_Load() ürününüz, aşağıdaki kod parçasına yazınız. Bütün problemlerin çözülecek.

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

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

Tip Form1_Load (veya ne şekilde olursa olsun) alt aşağıdaki kod: Burası kapalı çapraz iplik operasyonları ile tüm sorunları giderir

System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False 

.

+0

Not [güvenli sadece ayıklama sırasında çapraz parçacığı hatalarını önlemek için false CheckForIllegalCrossThreadCalls ayarlamak mı?] (http://stackoverflow.com/questions/13345091/is-it-safe)-sadece-to-checkforillegalcrossthreadcalls-için-yanlış-to-kaçınmak çapraz t ayarlayın. ** (yani, düzgün delegeleri oluşturun) kullanmak ve bunun yerine kod ile sorunları gidermek etmeyiniz. ** – cybermonkey

5

VB.NET'te bunun daha iyi bir yolu Extension kullanmaktır, çapraz iş parçacığı GUI Denetimi Çağrılar için çok güzel görünümlü bir kod oluşturur.

Sadece sahip herhangi Modülüne bu kod satırını ekleyin.

<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 

Artık herhangi bir denetim çağrısı için yalnızca 1 satır uzunluğunda Çapraz İş Denetim kodu yazabilirsiniz. Bunun gibi

, bir ComboBox temizlemek istediğiniz ve

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

açıkça sonra bir şey eklemek ister sadece şimdi yapmak kullanabilirsiniz ipliklerden veya dişler olmadan denir sağlar ki?

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

AutomationPeer'ı kullanmayı öner. Ben F5 tuşuna bastığınızda kod çağrıları Aşağıdaki örnek için

düğmeye yürütün. Benzer şekilde, bir iş parçacığı veya Arka Plan işçisinin bir olay veya işlev çağırmasını istiyorsanız, Otomasyon Eşlemesi'ni kullanabilirsiniz. Sizin durumunuzda (Ben burada kullandım) düğme yerine, çağırmak için uygun özelliği olan metin kutusunu kullanabilirsiniz.

'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 

Selamlar RV

0
CheckForIllegalCrossThreadCalls = False 
+0

bazı ek açıklama ekleyin. – rghome