简体   繁体   English

如何在 Visual Basic 中执行与 await await 等效的 C#

[英]How can I do the C# equivalent of await await in Visual Basic

I have a VB function which starts a program as a process and waits for it to complete.我有一个 VB function 将程序作为进程启动并等待它完成。 It passes a return code of zero if okay or 8 if not.如果没问题,它会通过返回码 0,否则会通过 8。 The problem is that it blocks the WPF UI thread and can lead to crashes of Not Enough Quota because the thread has been blocked for too long.问题是它阻塞了 WPF UI 线程,并可能导致 Not Enough Quota 崩溃,因为线程被阻塞的时间太长。

So I'm trying to make it run async so the UI thread isn't blocked.所以我试图让它异步运行,这样 UI 线程就不会被阻塞。 Unfortunately I have many lines of VB code but all the examples on various web sites these days are C# which I don't program in and I have far too much code to try and learn C# to convert it all.不幸的是,我有很多行 VB 代码,但是这些天在各种 web 网站上的所有示例都是 C#,我没有在其中进行编程,而且我有太多代码可以尝试学习 ZD7EFA19FBE7D3972FD5ADB6024223D7 来全部转换。

I've tried Await Task.Run which doesn't accept parameters.我试过 Await Task.Run 不接受参数。 I temporarily removed the Pgm parameter and hardcoded the program name and it will then compile and work.我暂时删除了 Pgm 参数并硬编码了程序名称,然后它将编译并工作。 I realise I could use global variables instead but that doesn't seem good practice.我意识到我可以改用全局变量,但这似乎不是一个好习惯。

TaskFactory seems to allow parameters but when I await on StartNew control returns immediately because StartNew creates an outer task and an inner task and the Await only waits for the initial outer task. TaskFactory 似乎允许参数,但是当我在 StartNew 上等待时,控件立即返回,因为 StartNew 创建了一个外部任务和一个内部任务,而 Await 只等待初始的外部任务。 A C# solution I've found suggests using Await Await Task but I can't seem to convert this to a syntax that VB will accept.我发现的 C# 解决方案建议使用 Await Await Task 但我似乎无法将其转换为 VB 将接受的语法。

Any help would be appreciated on how I can Await for Startit to complete.任何关于如何等待 Startit 完成的帮助将不胜感激。 I'm using.Net 6 and VS 2022 under Windows 10.我在 Windows 10 下使用.Net 6 和 VS 2022。

Please excuse any formatting errors.请原谅任何格式错误。 This is my first day on Stack Overflow这是我在 Stack Overflow 的第一天

The code编码

Class MainWindow
    Private Sub Button_Click(sender As Object, e As RoutedEventArgs)
        Call StartitAsync()
        MsgBox("Returned from StartitAsync")
    End Sub

    Private Async Function StartitAsync() As Task(Of Integer)
        Dim Startup As Func(Of String, Integer) = AddressOf Startit
        Dim tf As New TaskFactory
        Dim Rc As Integer = Await tf.StartNew(Startup, "notepad.exe")
        MsgBox("Returned from await of Startit, RC is " & Rc)
        Return Rc
    End Function

    Private Function Startit(Pgm As String) As Integer

        Dim RC As Integer
        Dim Startinfo As New ProcessStartInfo
        MsgBox("Pgm is " & Pgm)
        Startinfo.WindowStyle = ProcessWindowStyle.Maximized ' Display in a maximised window
        Startinfo.FileName = Pgm
        Startinfo.Arguments = ""
        Using PgmProcess As Process = Process.Start(startInfo:=Startinfo) ' Start the program
            PgmProcess.WaitForExit() ' Wait until it ends
            If PgmProcess.HasExited = True Then ' If the process has exited
                RC = PgmProcess.ExitCode ' Save the exit code
            Else
                RC = 8
            End If
        End Using
        Return RC
    End Function

You should use Task.Run instead of Task.Factory.StartNew (or (new TaskFactory()).StartNew ).您应该使用Task.Run而不是Task.Factory.StartNew (或(new TaskFactory()).StartNew )。 This is true for C# as well as VB.NET.这适用于 C# 和 VB.NET。

My VB is extremely rusty, but I believe this is what you're looking for:我的 VB 非常生锈,但我相信这就是你要找的:

Private Async Function StartitAsync() As Task(Of Integer)
  Dim Startup = Function() Startit("notepad.exe")
  Dim Rc As Integer = Await Task.Run(Startup)
  MsgBox("Returned from await of Startit, RC is " & Rc)
  Return Rc
End Function

This uses lambda expressions , which are very useful when using APIs like Task.Run .这使用lambda 表达式,这在使用诸如Task.Run类的 API 时非常有用。

Side note: You shouldn't call MsgBox from Startit .旁注:您不应该从Startit调用MsgBox Since Task.Run executes Startit on the thread pool, it shouldn't access any UI elements (or do things like show message boxes).由于Task.Run在线程池上执行Startit ,它不应访问任何 UI 元素(或执行显示消息框之类的操作)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM