{"id":3183,"date":"2008-12-30T12:00:00","date_gmt":"2008-12-30T12:00:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2008\/12\/30\/system-diagnostics-process-avoid-deadlocks-in-redirectstandardinputoutput-lucian-wischik\/"},"modified":"2024-07-05T13:34:12","modified_gmt":"2024-07-05T20:34:12","slug":"system-diagnostics-process-avoid-deadlocks-in-redirectstandardinputoutput-lucian-wischik","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/system-diagnostics-process-avoid-deadlocks-in-redirectstandardinputoutput-lucian-wischik\/","title":{"rendered":"System.Diagnostics.Process: avoid deadlocks in RedirectStandardInput\/Output (Lucian Wischik)"},"content":{"rendered":"<p>It&#8217;s&nbsp;common that you want to launch an external process but supply input and capture&nbsp;the output. Here&#8217;s&nbsp;one attempt:&nbsp;<span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">&#8216; BAD CODE<\/span><span lang=\"EN\"><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">Using<\/span><span lang=\"EN\"> p <span>As<\/span> <span>New<\/span> System.Diagnostics.Process<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.StartInfo.FileName = <span>&#8220;cat&#8221;<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.StartInfo.UseShellExecute = <span>False<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.StartInfo.RedirectStandardOutput = <span>True<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.StartInfo.RedirectStandardInput = <span>True<\/p>\n<p><\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.Start()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.StandardInput.Write(<span>&#8220;world&#8221;<\/span> &amp; vbCrLf &amp; <span>&#8220;hello&#8221;<\/span>)<\/span><span lang=\"EN\"><\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.StandardInput.Close()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> op = p.StandardOutput.ReadToEnd()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.WaitForExit()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>p.Close()<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\"><span>&nbsp;&nbsp;&nbsp; <\/span>Console.WriteLine(<span>&#8220;OUTPUT:&#8221;<\/span>) : Console.WriteLine(op)<\/p>\n<p><\/span><\/p>\n<p class=\"MsoNormal\"><span lang=\"EN\">End<\/span><span lang=\"EN\"> <span>Using<\/p>\n<p><\/span><\/span><\/p>\n<p>This code has a deadlock bug in it. That&#8217;s because of the possibility that &#8220;p&#8221; needs to write to StandardOutput before it&#8217;s yet finished reading all of StandardInput: there won&#8217;t be anyone to read from StandardOutput, and it might fill up!<\/p>\n<p>The <a class=\"\" href=\"http:\/\/msdn.microsoft.com\/en-us\/library\/system.diagnostics.processstartinfo.redirectstandardoutput.aspx\">MSDN documentation<\/a> says that the answer is to use multiple threads. So here&#8217;s code that uses multiple threads to avoid the deadlock:&nbsp;<a href=\"http:\/\/blogs.msdn.com\/lucian\/archive\/2008\/12\/29\/system-diagnostics-process-redirect-standardinput-standardoutput-standarderror.aspx\">http:\/\/blogs.msdn.com\/lucian\/archive\/2008\/12\/29\/system-diagnostics-process-redirect-standardinput-standardoutput-standarderror.aspx<\/a><\/p>\n<p>&nbsp;<\/p>\n<p><span><\/p>\n<p><\/span>&nbsp;<\/p>\n<p><\/span><\/p>\n","protected":false},"excerpt":{"rendered":"<p>It&#8217;s&nbsp;common that you want to launch an external process but supply input and capture&nbsp;the output. Here&#8217;s&nbsp;one attempt:&nbsp; &#8216; BAD CODE Using p As New System.Diagnostics.Process &nbsp;&nbsp;&nbsp; p.StartInfo.FileName = &#8220;cat&#8221; &nbsp;&nbsp;&nbsp; p.StartInfo.UseShellExecute = False &nbsp;&nbsp;&nbsp; p.StartInfo.RedirectStandardOutput = True &nbsp;&nbsp;&nbsp; p.StartInfo.RedirectStandardInput = True &nbsp;&nbsp;&nbsp; p.Start() &nbsp;&nbsp;&nbsp; p.StandardInput.Write(&#8220;world&#8221; &amp; vbCrLf &amp; &#8220;hello&#8221;) &nbsp;&nbsp;&nbsp; p.StandardInput.Close() &nbsp;&nbsp;&nbsp; Dim op = [&hellip;]<\/p>\n","protected":false},"author":260,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[192,195],"tags":[99],"class_list":["post-3183","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-featured","category-visual-basic","tag-lucian-wischik"],"acf":[],"blog_post_summary":"<p>It&#8217;s&nbsp;common that you want to launch an external process but supply input and capture&nbsp;the output. Here&#8217;s&nbsp;one attempt:&nbsp; &#8216; BAD CODE Using p As New System.Diagnostics.Process &nbsp;&nbsp;&nbsp; p.StartInfo.FileName = &#8220;cat&#8221; &nbsp;&nbsp;&nbsp; p.StartInfo.UseShellExecute = False &nbsp;&nbsp;&nbsp; p.StartInfo.RedirectStandardOutput = True &nbsp;&nbsp;&nbsp; p.StartInfo.RedirectStandardInput = True &nbsp;&nbsp;&nbsp; p.Start() &nbsp;&nbsp;&nbsp; p.StandardInput.Write(&#8220;world&#8221; &amp; vbCrLf &amp; &#8220;hello&#8221;) &nbsp;&nbsp;&nbsp; p.StandardInput.Close() &nbsp;&nbsp;&nbsp; Dim op = [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/3183","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/260"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=3183"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/3183\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=3183"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=3183"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=3183"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}