[C#] Почему рабочий поток переходит в состояние WaitSleepJoin?
а ты куда хочешь чтобы он перешел?
вот эти оба метода переводят в WaitSleepJoin
Thread.Sleep(1000);
Console.ReadLine.
Потому что tasklist запускается не "в рабочем потоке", а в отдельном процессе, ПОД УПРАВЛЕНИЕМ рабочего потока. А рабочий поток ожидает завершения процесса. Естественно, делает он это в состоянии WaitSleepJoin.
Thread.Sleep и Console.ReadLine не влияют на запущенный рабочий поток, т.к. выполняются в основном потоке.
Почему тогда, к примеру, ping или ipconfig так не делают?
Почему тогда, к примеру, ping или ipconfig так не делают?переходит в stopped, когда запущенный процесс завершается.
ping/ipconfig - у тебя завершаются, а tasklist не хочет.
скорее всего tasklist не хочет потому что у него вывод длинный, и он ждет когда ты у него вывод считаешь.
а вывод ping/ipconfig влазит в буфер, поэтому проскакивает.
Process)Proc).WaitForExit;
Здесь предлагают такое решение:
This problem can be solved by moving the ReadToEnd before the WaitForExit as follows.
Process p = new Process;
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
p.StartInfo.FileName = "test.exe";
p.Start;
string output = p.StandardOutput.ReadToEnd;
p.WaitForExit;
Только непонятно, почему нет возможности изменить размер буфера?
Только непонятно, почему нет возможности изменить размер буфера?это скорее всего виндовый буфер, чуть ли не в ядре, там его проблематично поменять.
using System;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Threading;
namespace ThreadProcessExample {
class Program {
static StringBuilder _output = new StringBuilder;
static void Main {
ProcessStartInfo ProcInfo = new ProcessStartInfo("tasklist") {
UseShellExecute = false,
RedirectStandardOutput = true
};
Process Proc = new Process { StartInfo = ProcInfo };
Proc.OutputDataReceived += new DataReceivedEventHandler(Proc_OutputDataReceived);
Thread th = new Thread(PerformProcess);
th.Start(Proc);
string answer = "";
while (answer != "y") {
Console.WriteLine("Working thread state is {0}", th.ThreadState);
Console.WriteLine("Abort thread? (y/n)");
answer = Console.ReadLine.ToLower;
if (answer == "y" && th.ThreadState != System.Threading.ThreadState.Stopped){
th.Abort;
}
}
Console.Read;
}
static void Proc_OutputDataReceived(object sender, DataReceivedEventArgs e) {
_output.Append(e.Data != "" ? e.Data+Environment.NewLine : "");
}
static void PerformProcess(object Proc) {
if (!(Proc is Process return;
try{
Process)Proc).Start;
Process) Proc).BeginOutputReadLine;
Process)Proc).WaitForExit;
Console.WriteLine(_output);
}
catch (ThreadAbortException) {
if (!Process)Proc).HasExited) Process)Proc).Kill;
Console.WriteLine("ThreadAbortException. \r\n"+_output);
}
}
}
}
Только пока не могу понять как в этом случае справляться процессами типа "ping localhost -t". Как сделать так, чтобы можно было выполнить Abort для рабочего потока?
только не рабочего потока, а запущенного процесса.
можешь кильнуть его: process.Kill,
для ping -t кошернее послать ему ctrl-c ( proc.StandardInput.WriteLine("\x3"); )
Просто идея была в том, чтобы останавливать процесс в обработчике исключения ThreadAbortException, которое инициируется при вызове Thread.Abort однако с Process.WaitForExit этот способ не подходит.
Попробовал вместо WaitForExit использовать перегрузку Process.WaitForExit(int milliseconds) и заработало как ожидалось: исключение ThreadAbortException инициируется, даже если не истек указанный период времени.
Оставить комментарий
ms_nadin
В таком примере - в рабочем потоке запускается утилита tasklist: