#.net #vb.net #winforms #asynchronous #process
#.net #vb.net #winforms #асинхронный #процесс
Вопрос:
Мне нужно выполнить процесс commandpromt асинхронно и получить результат выполнения. в настоящее время у меня есть этот код
Public Function ExecuteCommandSync(ByVal command As Object) As String
Dim result As String = Nothing
Try
Dim procStartInfo As New System.Diagnostics.ProcessStartInfo("cmd", "/c " amp; Convert.ToString(command))
procStartInfo.RedirectStandardOutput = True
procStartInfo.UseShellExecute = False
procStartInfo.CreateNoWindow = True
Dim proc As New System.Diagnostics.Process()
proc.StartInfo = procStartInfo
proc.Start()
result = proc.StandardOutput.ReadToEnd()
Console.WriteLine(result)
Catch objException As Exception
End Try
Return result
End Function
Пожалуйста, помогите мне преобразовать это в async без использования потока. возможно ли это?
Спасибо
Ответ №1:
Ниже приведен класс, который, я полагаю, достигает того, что вы ищете.
Процесс уже запущен асинхронно, я считаю, что то, что вы ищете, управляется событиями и скрыто. По какой-то причине вы специально хотите блокирующий вызов или боитесь многопоточности?
Если я не нахожусь на базе, и вы хотите, чтобы он блокировался, дайте мне знать, что мы тоже можем это сделать, хотя я не могу себе представить, почему.
По сути, это позволяет вам создавать командную оболочку и незаметно взаимодействовать с ней.
#Region " Imports "
Imports System.Threading
Imports System.ComponentModel
#End Region
Namespace Common
Public Class CmdShell
#Region " Variables "
Private WithEvents ShellProcess As Process
#End Region
#Region " Events "
''' <summary>
''' Event indicating an asyc read of the command process's StdOut pipe has occured.
''' </summary>
Public Event DataReceived As EventHandler(Of CmdShellDataReceivedEventArgs)
#End Region
#Region " Public Methods "
Public Sub New()
ThreadPool.QueueUserWorkItem(AddressOf ShellLoop, Nothing)
Do Until Not ShellProcess Is Nothing : Loop
End Sub
''' <param name="Value">String value to write to the StdIn pipe of the command process, (CRLF not required).</param>
Public Sub Write(ByVal value As String)
ShellProcess.StandardInput.WriteLine(value)
End Sub
#End Region
#Region " Private Methods "
Private Sub ShellLoop(ByVal state As Object)
Try
Dim SI As New ProcessStartInfo("cmd.exe")
With SI
.Arguments = "/k"
.RedirectStandardInput = True
.RedirectStandardOutput = True
.RedirectStandardError = True
.UseShellExecute = False
.CreateNoWindow = True
.WorkingDirectory = Environ("windir")
End With
Try
ShellProcess = Process.Start(SI)
With ShellProcess
.BeginOutputReadLine()
.BeginErrorReadLine()
.WaitForExit()
End With
Catch ex As Exception
With ex
Trace.WriteLine(.Message)
Trace.WriteLine(.Source)
Trace.WriteLine(.StackTrace)
End With
End Try
Catch ex As Exception
With ex
Trace.WriteLine(.Message)
Trace.WriteLine(.Source)
Trace.WriteLine(.StackTrace)
End With
End Try
End Sub
Private Sub ShellProcess_ErrorDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles ShellProcess.ErrorDataReceived
If Not e.Data Is Nothing Then RaiseEvent DataReceived(Me, New CmdShellDataReceivedEventArgs(e.Data))
End Sub
Private Sub ShellProcess_OutputDataReceived(ByVal sender As Object, ByVal e As System.Diagnostics.DataReceivedEventArgs) Handles ShellProcess.OutputDataReceived
If Not e.Data Is Nothing Then RaiseEvent DataReceived(Me, New CmdShellDataReceivedEventArgs(e.Data amp; Environment.NewLine))
End Sub
#End Region
End Class
<EditorBrowsable(EditorBrowsableState.Never)> _
Public Class CmdShellDataReceivedEventArgs : Inherits EventArgs
Private _Value As String
Public Sub New(ByVal value As String)
_Value = value
End Sub
Public ReadOnly Property Value() As String
Get
Return _Value
End Get
End Property
End Class
End Namespace