CallByName 和 Invoke 不是異步函式,所以我不能使用以下明顯的語法異步呼叫它們:
rv = await CallByName(objScripts, txtScript.Text, CallType.Method)
顯然我是唯一一個需要這個的人,所以互聯網上沒有答案。
我的用例是我有數百個用 vb.net 撰寫的資料庫轉換腳本。我有一個關于哪個腳本處理哪個資料庫的資料庫。然后,我的代碼讀取資料庫并在更新的資料庫到達時處理每個腳本,或者我可以從 UI 的下拉串列中選擇腳本并以這種方式運行。
我現在需要異步運行其中一些腳本,這樣我就可以使用 PuppeteerSharp 來抓取一些資料,而不是使用資料庫。
那么我該如何做呢?
uj5u.com熱心網友回復:
只需將結果轉換Task為await它
rv = Await DirectCast(CallByName(objScripts, txtScript.Text, CallType.Method), Task)
uj5u.com熱心網友回復:
好的,弄清楚了。
Private Async Function RunAScript_Worker(ScriptName As String, objScript As Object) As Task(Of Integer)
Try
Dim result As Task(Of Integer) = CType(objScript.GetType().GetMethod(ScriptName).Invoke(objScript, Nothing), Task(Of Integer))
Await result
Return result.Result
Catch ex As Exception
Throw ex
End Try
End Function
你這樣稱呼它:
rv = Await RunAScript_Worker(ScriptName, ClsContainingMethod)
這使用反射和 .Invoke 并通過添加Task(Of Integer)型別將其轉換為可等待的方法。
您還需要將 Async 添加到被呼叫的方法中,但是您可以將不需要的方法單獨放置,它會正常作業。
編輯:
嗯,差不多了。當我嘗試從未設定為異步的其他函式回傳值時,就會出現問題。await 需要一個 Task(of Integer) 但非異步函式只回傳 Integer 并且我得到一個運行時錯誤。
所以我想出了如何使用反射來確定該方法是否是異步的。我發現 GetMethod() 中的名稱引數是區分大小寫的,因此出于這個原因以及其他原因,我在執行該方法之前添加了檢查。我也比我更喜歡@Charlieface 的解決方案,所以:
If Not objScripts.GetType().GetMethod(ScriptName) Is Nothing Then
If objScripts.GetType().GetMethod(ScriptName).ReturnTypeCustomAttributes.ToString.Contains("Task") Then
Return Await DirectCast(CallByName(objScripts, ScriptName, CallType.Method), Task(Of Integer))
Else
Return CallByName(objScripts, ScriptName, CallType.Method)
End If
Else
' Exception handling
End If
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/439504.html
標籤:。网 VB.net 异步等待 callbyname
上一篇:按下幫助按鈕時顯示訊息框
