Async, Await bei Subs mit Process.Start()

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 8 Antworten in diesem Thema. Der letzte Beitrag () ist von VaporiZed.

    Async, Await bei Subs mit Process.Start()

    Hallo zusammen,

    wenn man seinen LAN-Adapter auf DHCP per WMI umstellt, muss dieser Adapter deaktiviert und wieder aktiviert werden, damit dieser sich auch komplett neu konfiguriert.
    Nun soll dies alles komplett im Hintergrund passieren und vor allem NACHEINANDER abgearbeitet werden.

    Deswegen hatte ich mir überlegt es per Async / Await zu verwirklichen.

    Ich habe mir schon den Thread Async, Await und Task angesehen, aber ich steige da einfach nicht durch.

    Könnt ihr mir es bitte an meinem Code erklären, wo man den Await einbauen muss und wie man es anstellt, dass diese 3 Subs nach einander abarbeiten lässt? Also vielleicht eine Übergabe von dem Sub zuvor, sobald dieser fertig ist!?

    Aus meiner Hauptform rufe ich per Button den Code in einem Modul auf :

    VB.NET-Quellcode

    1. Private Sub DHCP_Button_Click(sender As Object, e As EventArgs) Handles DHCPButton.Click
    2. DHCPButton.Enabled = False
    3. Test_Module.DHCP_Teil1_Umstellung()
    4. Test_Module.DHCP_Teil2_Off()
    5. Test_Module.DHCP_Teil3_On()
    6. DHCPButton.Enabled = True
    7. End Sub


    Im Modul ist dann der eigentliche Code :

    VB.NET-Quellcode

    1. ​ Async Sub DHCP_Teil1_Umstellung()
    2. Dim objMC As ManagementClass = New ManagementClass("Win32_NetworkAdapterConfiguration")
    3. Dim objMOC As ManagementObjectCollection = objMC.GetInstances()
    4. For Each objMO As ManagementObject In objMOC
    5. If (Not CBool(objMO("IPEnabled"))) Then
    6. Continue For
    7. End If
    8. Try
    9. Dim objNewIP As ManagementBaseObject = Nothing
    10. Dim objSetIP As ManagementBaseObject = Nothing
    11. Dim objNewDNS As ManagementBaseObject = Nothing
    12. Dim objSetDNS As ManagementBaseObject = Nothing
    13. objNewIP = objMO.GetMethodParameters("EnableDHCP")
    14. objSetIP = objMO.InvokeMethod("EnableDHCP", Nothing, Nothing)
    15. objNewDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder")
    16. objSetDNS = objMO.InvokeMethod("SetDNSServerSearchOrder", Nothing, Nothing)
    17. SetDNSAutomatically((objMO.GetPropertyValue("settingID").ToString))
    18. Catch ex As Exception
    19. MessageBox.Show("Settings unchanged : " & ex.Message)
    20. End Try
    21. Next objMO
    22. End Sub
    23. Public Sub SetDNSAutomatically(ByVal settingID As String)
    24. Const conKeyPath = "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces"
    25. If settingID = String.Empty Then
    26. Throw New ArgumentNullException("settingID")
    27. End If
    28. Dim _adapterKeyPath = String.Format("{0}\{1}", conKeyPath, settingID)
    29. My.Computer.Registry.SetValue(_adapterKeyPath, "NameServer", String.Empty)
    30. End Sub
    31. Async Sub DHCP_Teil2_Off()
    32. Dim Deaktivieren As New Process()
    33. Deaktivieren.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
    34. Deaktivieren.StartInfo.FileName = "netsh"
    35. Deaktivieren.StartInfo.Arguments = "interface set interface name=LAN-Verbindung1 admin=DISABLE"
    36. Deaktivieren.Start()
    37. Deaktivieren.WaitForExit()
    38. End Sub
    39. Async Sub DHCP_Teil3_On()
    40. Dim Aktivieren As New Process()
    41. Aktivieren.StartInfo.WindowStyle = ProcessWindowStyle.Hidden
    42. Aktivieren.StartInfo.FileName = "netsh"
    43. Aktivieren.StartInfo.Arguments = "interface set interface name=LAN-Verbindung1 admin=ENABLE"
    44. Aktivieren.Start()
    45. Aktivieren.WaitForExit()
    46. End Sub
    Mach mal alle Deine Async-Modifikatoren weg und teste das mal:

    VB.NET-Quellcode

    1. Private Async Sub DHCP_Button_Click(sender As Object, e As EventArgs) Handles DHCPButton.Click
    2. DHCPButton.Enabled = False
    3. Await Threading.Tasks.Task.Run(Sub()
    4. Test_Module.DHCP_Teil1_Umstellung()
    5. Test_Module.DHCP_Teil2_Off()
    6. Test_Module.DHCP_Teil3_On()
    7. End Sub)
    8. DHCPButton.Enabled = True
    9. End Sub

    Was nacheinander abgearbeitet werden soll, wird normal zu einem Block zusammengefasst. Wenn dieser Block im Hintergrund ablaufen soll, wird vor diesen Block ein Await gesetzt. Was nach dem Awaitable Block geschrieben wird, wird ausgeführt, sobald der Block fertig abgearbeitet ist.

    Alternativ kannst Du auch schreiben:

    VB.NET-Quellcode

    1. Private Async Sub DHCP_Button_Click(sender As Object, e As EventArgs) Handles DHCPButton.Click
    2. DHCPButton.Enabled = False
    3. Await Threading.Tasks.Task.Run(Sub() DHCP_Change())
    4. DHCPButton.Enabled = True
    5. End Sub
    6. Private Sub DHCP_Change()
    7. Test_Module.DHCP_Teil1_Umstellung()
    8. Test_Module.DHCP_Teil2_Off()
    9. Test_Module.DHCP_Teil3_On()
    10. End Sub
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    ​Threading.Tasks.Task.Run
    "Run" ist kein Member von "Task"... Warum bekomme ich das als Fehler?
    Imports System.Threading.Tasks habe ich gemacht!


    Verstehe ich es richtig, das der

    Quellcode

    1. Private Sub DHCP_Change()
    auf jeden Fall wartet, bis

    Quellcode

    1. Test_Module.DHCP_Teil1_Umstellung()
    komplett fertig ist, bevor er den nächsten (

    Quellcode

    1. Test_Module.DHCP_Teil2_Off()
    ) startet?

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „zauber777“ ()

    Welche Frameworkversion nutzt Du? Schraub mal auf 4.7.2 oder 4.8 hoch.
    Ja, Deine Vermutung ist richtig. Soll doch so sein, oder?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Mein Zielframework ist auf ".Net Framework 4 Client Profile" eingestellt. Habe gerade auf dem Zielrechner geschaut, da ist Netframework v4.0.30319 installiert.
    Ist Async / Await / Task überhaupt in dem Framework möglich oder bin ich gezwungen auf dem dem Zielsystem ein Update zu machen?

    Ja genau so soll es auch sein. :)

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „zauber777“ ()

    Async/Await ist ja zum KeyWord gemacht worden. Das ist m.E. Fraework-unabhängig. Task.Run geht laut MSDN-Artikel erst ab 4.5. Bekommt man bestimmt auch ohne Task.Run hin, bin nur gerade zu faul zum Recherchieren :rolleyes:
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    ok, habe mich dazu entschieden die Zielsysteme auf Net Framework 4.5 zu updaten.
    Jedoch bekomme ich bei beiden Versionen (aus Post #2) die Execution-Fehler "Der Objektverweis wurde nicht auf eine Objektinstanz festgelegt." Im Code selbst in Visual Studio wird mir aber kein Fehler angezeigt. Woran könnte das liegen?
    Async/Await mag zwar ein keyword sein, wie jedoch foreach, bei dem die Klasse eine Funktion GetEnumerator() (evtl. noch andere) vorweisen muss, muss in der Klasse die Awaitet wird, eine Funktion GetAwaiter() gegeben sein, die es in den Tasks von .NET 4.0 noch nicht gegeben hat. Zwar gab es mal ein Preview-Package für .NET 4.0, jedoch ist das afaik buggy und nur mit VS2010 verwendbar.

    tl;dr:
    async/await funktioniert erst ab .NET 4.5

    @zauber777 Dann Debugge doch mal dein Programm Schritt für Schritt und sehr dir an, warum welche Variable nicht initialisiert wurde
    In Post#2 verwende ich nur eine Variable und das ist ein Boolean, auf die die Meldung nicht zutreffen kann. Von daher: Welche Variable ist in welcher Zeile in Post#1 betroffen?
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.