C# 'System.InvalidOperationException' Cann

2019-04-14 05:15发布

I am trying to read from a CMD process repeatedly, and print out the output repeatedly as well, But the while loop I am using is inside a Task.Run so that it doesn't lock the program up, but there is some problem with ASync and non-ASync methods that I don't quite understand. I get that I need to not have the pProcess.StandardOutput.ReadToEnd in a Task.Run, but how would I implement this in my code? Thanks!

Task.Run(() => 
    {
        while (true)
        {
            string output = pProcess.StandardOutput.ReadToEnd();
            System.Console.Write(output);
        }
     });

enter image description here

4条回答
forever°为你锁心
2楼-- · 2019-04-14 05:44

Assuming pProcess is an instance of Process, pProcess.StandardOutput is asynchronous, but keeps reading until the end because of the .readToEnd() method.
I don't think you need Task.Run or the while loop. Check out the example at https://msdn.microsoft.com/en-us/library/system.diagnostics.process.beginoutputreadline%28v=vs.110%29.aspx

查看更多
狗以群分
3楼-- · 2019-04-14 05:54

I have solves this problem your are using Standardoutput.
you must use once for one object
string output = pProcess.StandardOutput.ReadToEnd();
OR

pProcess.BeginOutputReadLine();

You cannot use both at a same time on single object. So if you want to read output and wait as well while the process not complete use

string output = pProcess.StandardOutput.ReadToEnd();

if you do not want to read output just simple you can use

pProcess.BeginOutputReadLine();

well you can use both according to your need but not at the same time.

查看更多
干净又极端
4楼-- · 2019-04-14 05:57

Could you please try the following code snippet? OutputDataReceived is the method to asynchronously read process output.

var startInfo = new ProcessStartInfo {
    FileName = <Your Application>,
    UseShellExecute = false, // Required to use RedirectStandardOutput
    RedirectStandardOutput = true, //Required to be able to read StandardOutput
    Arguments = <Args> // Skip this if you don't use Arguments
};

using(var process = new Process { StartInfo = startInfo })
{
    process.Start();

    process.OutputDataReceived += (sender, line) =>
    {
        if (line.Data != null)
            Console.WriteLine(line.Data);
    };

    process.BeginOutputReadLine();

    process.WaitForExit();
}
查看更多
干净又极端
5楼-- · 2019-04-14 06:02

There's no problem with executing this code in a seperate Task with Task.Run I think you're calling some asynchronous method like BeginErrorReadLine or BeginOutputReadLine somewhere before in your code. This SO answer may help: I am trying to read the output of a process in c# but I get this message "Cannot mix synchronous and asynchronous operation on process stream."

查看更多
登录 后发表回答