lab*_*b12 13 vb.net multithreading visual-studio-2010
我正在使用vb.net,并且在我的程序中,当我运行我的后台工作程序时,我会得到这个'crossthread操作无效'错误,这将使此文本框启用为true.我的主要sub将首先将enabled设置为false,当backgroundworker运行时,它将返回true,然后退出.为什么它会给我一个错误?仅供参考:有更多的代码,但我不想让它更令人困惑......
这是堆栈跟踪:
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)
Run Code Online (Sandbox Code Playgroud)
这是确切的错误消息:
{"Cross-thread operation not valid: Control 'mainText' accessed from a thread other than the thread it was created on."}
Run Code Online (Sandbox Code Playgroud)
有人可以帮帮我!
谢谢,
凯文
Dan*_*Tao 21
BackgroundWorker
该类的目的是在GUI保持响应的同时在非GUI线程上执行工作.除非您设置Control.CheckForIllegalCrossThreadCalls
为false
(您不应该这样做),或者Invoke
按照其他答案(我也不建议)的建议使用,否则您将获得非法的跨线程操作异常.
如果你想GUI相关的"东西"的出现,而你BackgroundWorker
正在运行,我一般建议您使用BackgroundWorker.ReportProgress
方法和安装合适的处理器的BackgroundWorker.ProgressChanged
事件.如果你想在GUI上的东西,一旦发生BackgroundWorker
被完成,然后简单地附上您的处理程序来更新GUI的BackgroundWorker.RunWorkerCompleted
事件.
小智 13
在Form1_Load
(或任何形式)sub中键入以下代码:
System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = False
Run Code Online (Sandbox Code Playgroud)
它修复了阻塞的跨线程操作的所有问题.
Fre*_*örk 11
你在哪里设置了Enabled
房产?如果您在DoWork
事件处理程序中执行此操作,则此代码在与创建按钮不同的线程上运行,这应该提供您遇到的异常.要解决这个问题,你应该使用BeginInvoke
.为方便起见,它可以包装到一个方法中,如下所示:
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
Run Code Online (Sandbox Code Playgroud)
现在,您可以安全地调用该方法来启用或禁用任何线程的任何控件:
SetControlEnabled(someButton, False)
Run Code Online (Sandbox Code Playgroud)
在VB.NET中更好的方法是使用Extension
它为跨线程GUI控制调用制作非常漂亮的代码.
只需将此行代码添加到您拥有的任何模块中即可.
<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
Run Code Online (Sandbox Code Playgroud)
现在,您可以编写跨线程控制代码,该代码对于任何控制调用只有1行长.
像这样,让我们说你要清除一个ComboBox,它是从线程调用的,或者没有线程,你现在就可以使用它
cboServerList.Invoke(Sub() cboServerList.Items.Clear())
Run Code Online (Sandbox Code Playgroud)
想要在清除后添加一些东西吗?
cboServerList.Invoke(Sub() cboServerList.Items.Add("Hello World"))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
61442 次 |
最近记录: |