【问题标题】:Is correct to call a function from a BackGroundWorker?从 BackGroundWorker 调用函数是否正确?
【发布时间】:2015-02-18 14:27:30
【问题描述】:

我有一个应用程序,它从数据库中获取数据,对其进行处理,然后将其发送到定义的 IP。我想让它使用 BackgroundWorker 以避免停止 GUI。

BackgroundWorker 事件处理程序中的代码太长且太复杂,因此我正在考虑将该代码拆分为多个函数以更好地组织代码。

这样好吗?我可以在同一个Form1 类中编写这些函数并从BackgroundWorker 调用它们吗?我需要创建一个新班级吗?

【问题讨论】:

    标签: vb.net function backgroundworker


    【解决方案1】:

    是的,这是完全可以接受的,如果不是最好的话。问题不在于您是否从BackgroundWorker 事件中调用其他方法。相反,问题是这些函数实际上做什么。如果他们正在修改 UI 控件,这是不可接受的,无论是完成还是事件处理程序或单独的函数。同样,如果他们使用与 UI 线程共享而没有SyncLock 的线程不安全对象,那么这在任何一个地方都是一个问题。所以,是的,只要正在执行的工作是线程安全的,那么无论是在事件处理程序、单独的方法,还是在另一个类或库中完成都没有关系。

    例如,如果您的方法需要从后台线程更新RichTextBox 控件,您可以执行以下操作:

    Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        GenerateReport()
    End Sub
    
    Private Sub GenerateReport()
        Dim rtf As String = ' ...
        Me.Invoke(Sub() RichTextBox1.Rtf = rtf)
    End Sub
    

    【讨论】:

    • 好的,谢谢你的例子;我现在明白了。你在最后一行使用了 lambda 表达式,对吧?
    • 是的。这不是必需的。您可以将委托用于普通方法,但是,正如您所见,lambda 表达式对于这类事情特别有用。
    • 那么,我可以直接调用 Delegate 还是应该将 lambda 表达式中的“RichTextBox1.Rtf = rtf”替换为“WriteRTBLog(rtf,Color)”?
    • 是的,你可以改变 lambda 表达式来调用任何方法或设置你想要的任何属性。
    【解决方案2】:

    BackgroundWorker 当然可以调用函数。与 BackgroundWorker 的 DoWork 方法中的代码一样,您需要确保函数中的代码不会尝试更新与主线程中的代码正在更新的对象相同的对象。例如,您需要避免更新 UI 控件,或者使用线程安全的方式来执行此操作。

    【讨论】:

    • 目前我有一个 RichTextBox,我通过委托进行更新。我也必须避免打电话给那个代表?我用它作为日志
    • 任何时候你需要触摸一个UI控件,比如来自后台线程的RichTextBox,你需要调用表单或控件的InvokeBeginInvoke方法,给它一个委托给更新控件的方法。
    • 我没听懂你在向我解释什么。您是否想告诉我直接从 BackGroundWorker 调用 Delegate 是不行的,我应该对 Form1 执行 Invoke 然后调用 Delegate?我需要在Google上进行研究,我应该直接搜索“Invoke”吗?我不知道这是否会给我带来我需要了解你的结果。
    • 我已经更新了答案,包括使用Invoke 从后台线程更新RichTextBox 的示例。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-01-03
    • 1970-01-01
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 2019-10-23
    • 1970-01-01
    相关资源
    最近更新 更多