【问题标题】:Accessing UI thread controls from 2 joining multi thread从 2 个加入多线程访问 UI 线程控件
【发布时间】:2016-03-15 00:44:13
【问题描述】:

我目前正在为我的公司开发一个小型自动更新项目。经过对多线程的一些研究,我设法构建了以下代码:

主题 #01:

Private Sub startUpdate()
    If InvokeRequired Then
        Invoke(New FTPDelegate(AddressOf startUpdate))
    Else
        'some code here
    End If
End Sub

线程 #02 由线程 #01 连接:

Private Sub startProcess()
    myThread = New Thread(Sub() startUpdate())
    myThread.Start()
    myThread.Join()

    'another code goes here

    Me.close
End Sub

当表单加载时访问线程#02:

Private Sub SUpdater_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    myThread1 = New Thread(Sub() startProcess())
    myThread1.Start()
End Sub

有两件事我被困住了:

  • 我无法从线程 #01 访问 Me.close。它会引发错误:

    控件在另一个线程中

  • 即使我调用了另一个线程,主窗体也会冻结。

请帮我解决这个错误。

非常感谢。

【问题讨论】:

  • 您必须调用 Me.Close() 调用,就像您在此处所做的那样:Invoke(New FTPDelegate(AddressOf startUpdate))
  • @VisualVincent 我应该在哪里调用 Me.close?我是否应该将其设为一个单独的函数并像调用 startUpdate 函数一样调用它?
  • 我已经添加了一个更彻底的解释答案。
  • 可能想要使用Task 而不是普通的Thread

标签: vb.net multithreading


【解决方案1】:

每次访问 UI 元素时都需要调用。调用Me.Close() 开始处理表单的所有元素(组件、按钮、标签、文本框等),从而导致与表单本身以及其中的所有内容进行交互。

您唯一不需要调用的是 properties,您知道在获取或设置时不会修改 UI 上的任何内容,还有 fields(又名变量)。

例如,这不需要调用:

Dim x As Integer = 3

Private Sub Thread1()
    x += 8
End Sub

要解决您的问题,您只需调用表单的关闭。这可以简单地使用委托来完成。

Delegate Sub CloseDelegate()

Private Sub Thread1()
    If Me.InvokeRequired = True Then 'Always check this property, if invocation is not required there's no meaning doing so.
        Me.Invoke(New CloseDelegate(AddressOf Me.Close))
    Else
        Me.Close() 'If invocation is not required.
    End If
End Sub

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-02
    • 2021-07-30
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    相关资源
    最近更新 更多