.net - What is the difference between p.WaitForExit() and p.WaitForExit(Integer.MaxValue) in this specific case? -
.net - What is the difference between p.WaitForExit() and p.WaitForExit(Integer.MaxValue) in this specific case? -
basically i'm launching asynchronously process
, i'm waiting process
exit using task
, don't have problems code below, i've found little issue understand...
the issue if utilize method process.waitforexit()
, seek cancel task
(or same, kill process) process never exits sub-thread hangs forever, instead if utilize method process.waitforexit(integer.maxvalue)
works perfectlly.
why happens that?, difference makes process unable recognize process has exited?.
the process
instance:
''' <summary> ''' cmd <see cref="system.diagnostics.process"/> instance. ''' </summary> private withevents cmdprocess new process { .enableraisingevents = true, .startinfo = new processstartinfo { .filename = "cmd.exe", .arguments = string.empty, .redirectstandardinput = false, .redirectstandardoutput = true, .redirectstandarderror = true, .useshellexecute = false, .createnowindow = true } }
the task
initializer:
private sub starttask() me.cmdtask = task.factory.startnew(addressof cmdautomate) me.cmdtaskcts = new threading.cancellationtokensource me.cmdtaskct = cmdtaskcts.token end sub
the job task
does:
private sub cmdautomate() me.cmdprocess .startinfo.arguments = string.format("/c ""{0}""", me.pingarguments) .start() .beginoutputreadline() .beginerrorreadline() .waitforexit(integer.maxvalue) end end sub
and task
canceller:
private sub canceltask() if not me.cmdprocess.hasexited me.cmdprocess .canceloutputread() .cancelerrorread() .kill() ' kill process (cmd.exe) end ' cancel task. me.cmdtaskcts.cancel() ' wait task cancellation finishes. me.cmdtask.wait() end if end sub
this entire code if needed:
imports system.threading imports system.threading.tasks public class form1 private cmdtask task private cmdtaskcts new cancellationtokensource private cmdtaskct cancellationtoken ''' <summary> ''' cmd <see cref="system.diagnostics.process"/> instance. ''' </summary> private withevents cmdprocess new process { .enableraisingevents = true, .startinfo = new processstartinfo { .filename = "cmd.exe", .arguments = string.empty, .redirectstandardinput = false, .redirectstandardoutput = true, .redirectstandarderror = true, .useshellexecute = false, .createnowindow = true } } ''' <summary> ''' gets ping commandline arguments. ''' </summary> private readonly property pingarguments string homecoming string.format("ping.exe -t ""{0}.{1}.{2}.{3}""", textbox1.text, textbox2.text, textbox3.text, textbox4.text) end end property private sub btnsend_click(byval sender object, byval e eventargs) _ handles btnsend.click me.starttask() end sub private sub cmdautomate() me.cmdprocess .startinfo.arguments = string.format("/c ""{0}""", me.pingarguments) .start() .beginoutputreadline() .beginerrorreadline() .waitforexit(integer.maxvalue) end end sub ''' <summary> ''' occurs when application writes redirected <see cref="system.diagnostics.process.standardoutput"/> stream. ''' occurs when application writes redirected <see cref="system.diagnostics.process.standarderror"/> stream. ''' </summary> private sub cmdprocess_outputdatareceived(byval sender object, byval e datareceivedeventargs) _ handles cmdprocess.outputdatareceived, cmdprocess.errordatareceived select case txtresults.invokerequired case true txtresults.invoke(sub() txtresults.appendtext("" & e.data)) txtresults.invoke(sub() txtresults.appendtext(environment.newline)) case else txtresults.appendtext(e.data) txtresults.appendtext(environment.newline) end select #if debug ' debug.writeline(e.data) #end if end sub ''' <summary> ''' occurs when <see cref="system.diagnostics.process"/> exits. ''' </summary> private sub cmdprocess_exited(byval sender object, byval e eventargs) _ handles cmdprocess.exited debug.writeline(string.format("cmdprocess has exited exit code: {0}", directcast(sender, process).exitcode)) end sub private sub linklabel1_linkclicked(sender object, e linklabellinkclickedeventargs) _ handles linklabel1.linkclicked ' limpio el texto de cada textbox. each tb textbox in me.controls.oftype(of textbox)() tb.clear() next tb ' cancelo la tarea en segundo plano. me.canceltask() end sub private sub starttask() me.cmdtask = task.factory.startnew(addressof cmdautomate) me.cmdtaskcts = new threading.cancellationtokensource me.cmdtaskct = cmdtaskcts.token end sub private sub canceltask() ' si el proceso no se ha detenido... if not me.cmdprocess.hasexited me.cmdprocess ' cancelo la lectura de los outputs. .canceloutputread() .cancelerrorread() .kill() ' mato el proceso (cmd.exe) end ' cancelo la tarea en segundo plano. me.cmdtaskcts.cancel() ' espero que la tarea se haya cancelado. me.cmdtask.wait() end if end sub end class
from can tell reading this, , limited experience asynchronous tasks, may have fact .waitforexit called within task, after start. msdn page on process.kill has using kill , waitforexit: "the kill method executes asynchronously. after calling kill method, phone call waitforexit method wait process exit, or check hasexited property determine if process has exited."
in case waitforexit beingness called before kill, called if task cancelled. waitforexit(int32) working because wait amount of time, instead of indefinitely (as going here).
see msdn pages waitforexit: http://msdn.microsoft.com/en-us/library/system.diagnostics.process.waitforexit%28v=vs.110%29.aspx,
and http://msdn.microsoft.com/en-us/library/fb4aw7b8%28v=vs.110%29.aspx?cs-save-lang=1&cs-lang=vb#code-snippet-1.
i hope helps, anyway.
.net vb.net multithreading asynchronous process
Comments
Post a Comment