我在此之外还有一个函数,一旦该线程结束,我想调用该函数。
Public Sub Replace(ByVal p_objStation As voapPlanningStation, _
ByVal p_objGenset As voapPlanningGenset, _
ByVal p_arlValues As ArrayList)
'PUT below in a thread
Dim i As Int32 = 0
Dim tasks As Task() = New Task(4) {}
mobjParty.ReplaceGensetMEL(p_objStation, p_objGenset, p_arlValues)
'put this in a thread
Me._replaceMELThread = New System.Threading.Thread(Sub() Me.ReplaceMELThreadSafe(p_objStation, p_objGenset, p_arlValues))
Me._replaceMELThread.Start()
End Sub
答案 0 :(得分:2)
基于显式Threading
对象的Thread
API非常注重机制。 “我需要另一个线程来运行一些代码,因此我将创建一个线程并使其运行代码”。但是,当时在设计上没有太多考虑允许以后会合-Join
阻塞当前线程,直到Join
ed线程退出,所以就阻塞了您。
但是,不想阻塞UI是一种普遍的愿望。因此,框架团队创建了BackgroundWorker
。这给您问题的抽象。工作线程中的不同方法在UI线程或某个其他线程中运行,并且您不必担心其他线程来自何处或在使用后会去向何方。 。您只需例如更新UI ProgressChanged
或RunWorkerCompleted
。
但是,这种抽象还远远不够。人们普遍希望能够说:“我有很多工作要做,我不在乎代码在哪里运行,我所关心的就是能够找到完整的代码。并获得结果”。这是Task
API。任务的运行方式,幕后存在的线程是无关的实现细节。
由于async
/ await
已添加到语言中,因此这是与Task
进行交互的最“自然”的工作。 await
的关键之处在于,如果您尚未await
完成某项操作,它会释放您当前的线程(而不是阻塞线程)。如果您的用例不适合ContinueWith
,但大多数情况下适合,您也可以使用await
。
对于不应阻塞UI的CPU密集型工作,请使用Task.Run
。
答案 1 :(得分:0)
这非常简单,请在某处使用下面的函数async/await pattern和Await
,包含新Await
语句的那一行之后的最后一行将在之后执行此方法已完成工作:
Async Function Replace(ByVal p_objStation As voapPlanningStation, _
ByVal p_objGenset As voapPlanningGenset, _
ByVal p_arlValues As ArrayList) As Task
'concurrently wait for task completion
Await Task.Run(Sub() mobjParty.ReplaceGensetMEL(p_objStation, p_objGenset, p_arlValues))
'concurrently wait for task completion
Await Task.Run(Sub() Me.ReplaceMELThreadSafe(p_objStation, p_objGenset, p_arlValues))
End Sub