【问题标题】:Can Background workers share functions后台工作者可以共享功能吗
【发布时间】:2020-07-23 23:06:51
【问题描述】:

我有一个相当复杂的窗口窗体应用程序,它管理着 2 个后台工作线程。一切都按预期运行,但我发现自己写了两次,每个后台工作人员一次,我不确定这是否需要。例如,我在其中一个 Do_Work 例程中:

Do While ThisQueue.FIleList.Count > 0
  ..Do some work..
  Call Worker1DoSomething(SomeVar)
  ..Do more work..
Loop

在第二个后台工作人员的 Do_Work 例程中,我有:

Do While ThisQueue.FileList.Count > 0
  ..Do some work..
  Call Worker2DoSomething(SomeVar)
  ..Do more work..
Loop

我可以让两个 Do_Work 例程都调用 1 个函数而不把事情搞砸吗?而不是两个函数:Worker1DoSomething(byval thisvar as string) 和 Worker2DoSometing(byval thisvar as string) 只有 1 个函数 WorkerFunctionDoSomething(byval thisvar as string)?

我问的最大原因是我有 8 个函数,实际上是从 Do_Work 例程调用的 4 个函数,这将大大简化代码。其中一个函数将数据写入 SQL 服务器,这也是我开始采用这种方法的主要原因。

提前感谢您的任何帮助或建议! 弗雷德

【问题讨论】:

  • 这两个工作线程是否同时运行?如果是这样,您需要一些锁定方法,以避免并发、重叠、调用可能(将)不喜欢它的过程、同时使用相同的集合/对象/变量等。
  • Call 关键字是为了向后兼容旧的 vb6 时代代码而存在的东西之一。没有理由在 VB.Net 中使用它,它实际上并没有做任何事情。即使是文档中的示例也可以使用括号更好地处理。
  • Jimi;是的,两个工作线程同时运行,这就是我现在这样写的原因,不希望出现任何并发或重叠问题。乔尔:旧习惯很难改掉。 :) 我不假思索地在这里输入了代码。我仍然发现自己有时会在编辑器中输入它。谢谢提醒!

标签: vb.net


【解决方案1】:

你当然可以做到。与任何事件处理程序一样,在DoWork 事件处理程序内部,sender 参数是引发事件的对象。如果您在每个BackgroundWorker 与您希望它使用的数据和/或您要执行的方法之间建立关系,您可以使用sender 来获取该数据和/或方法并利用它们。一种方法是使用 DictionaryBackgroundWorker 对象作为键:

Private ReadOnly workMethodsByWorker As New Dictionary(Of BackgroundWorker, Action(Of Object)) From {{BackgroundWorker1, AddressOf Method1},
                                                                                                     {BackgroundWorker2, AddressOf Method2}}

Private data As Object

Private Sub BackgroundWorkers_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork,
                                                                                     BackgroundWorker2.DoWork
    Dim worker = DirectCast(sender, BackgroundWorker)
    Dim method = workMethodsByWorker(worker)

    method(data)
End Sub

Private Sub Method1(data As Object)
    '...
End Sub

Private Sub Method2(data As Object)
    '...
End Sub

另一种选择是定义您自己的类,该类继承BackgroundWorker,并为要执行的方法添加一个属性,并使用该类而不是标准的BackgroundWorker

Imports System.ComponentModel

Public Class BackgroundWorkerEx
    Inherits BackgroundWorker

    Public Property WorkMethod As Action(Of Object)

End Class
Private data As Object

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    BackgroundWorkerEx1.WorkMethod = AddressOf Method1
    BackgroundWorkerEx2.WorkMethod = AddressOf Method2
End Sub

Private Sub BackgroundWorkers_DoWork(sender As Object, e As DoWorkEventArgs)
    Dim worker = DirectCast(sender, BackgroundWorkerEx)
    Dim method = worker.WorkMethod

    method(data)
End Sub

Private Sub Method1(data As Object)
    '...
End Sub

Private Sub Method2(data As Object)
    '...
End Sub

【讨论】:

  • 嗨,Jmcil;我喜欢你的第一个建议;我已经在使用基本类对象将婴儿车传递到每个 Do_Worker 例程中。我可以将函数添加到此类并从 Do_work 例程中调用它,对吗?例如,我有一个名为 WorkerPrams.vb 的类,它具有许多公共属性和公共函数,它们作为 e 传递到 Do_Work 例程中,然后检索: Dim Params as WorkerPrams = e.arguement 从这里,我可以调用 Params .Function(value) 大约对吗?超级感谢您的指导...我会尽快发布我的结果!
  • 只是想表明这已解决;完美!好主意JMcil!整理主模块。感谢大家的发帖和帮助!
猜你喜欢
  • 2018-01-10
  • 1970-01-01
  • 2018-03-03
  • 1970-01-01
  • 2015-05-07
  • 1970-01-01
  • 2019-04-29
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多