失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > c# 备份oracle waitforexit()方法死锁 ProcessStartInfo挂在“WaitForExit”上?为什么?

c# 备份oracle waitforexit()方法死锁 ProcessStartInfo挂在“WaitForExit”上?为什么?

时间:2020-10-20 09:41:00

相关推荐

c# 备份oracle waitforexit()方法死锁 ProcessStartInfo挂在“WaitForExit”上?为什么?

实施 H1>

public static async Task StartProcess(

string filename,

string arguments,

string workingDirectory= null,

int? timeout = null,

TextWriter outputTextWriter = null,

TextWriter errorTextWriter = null)

{

using (var process = new Process()

{

StartInfo = new ProcessStartInfo()

{

CreateNoWindow = true,

Arguments = arguments,

FileName = filename,

RedirectStandardOutput = outputTextWriter != null,

RedirectStandardError = errorTextWriter != null,

UseShellExecute = false,

WorkingDirectory = workingDirectory

}

})

{

process.Start();

var cancellationTokenSource = timeout.HasValue ?

new CancellationTokenSource(timeout.Value) :

new CancellationTokenSource();

var tasks = new List(3) { process.WaitForExitAsync(cancellationTokenSource.Token) };

if (outputTextWriter != null)

{

tasks.Add(ReadAsync(

x =>

{

process.OutputDataReceived += x;

process.BeginOutputReadLine();

},

x => process.OutputDataReceived -= x,

outputTextWriter,

cancellationTokenSource.Token));

}

if (errorTextWriter != null)

{

tasks.Add(ReadAsync(

x =>

{

process.ErrorDataReceived += x;

process.BeginErrorReadLine();

},

x => process.ErrorDataReceived -= x,

errorTextWriter,

cancellationTokenSource.Token));

}

await Task.WhenAll(tasks);

return process.ExitCode;

}

}

///

/// Waits asynchronously for the process to exit.

///

/// The process to wait for cancellation.

/// A cancellation token. If invoked, the task will return

/// immediately as cancelled.

/// A Task representing waiting for the process to end.

public static Task WaitForExitAsync(

this Process process,

CancellationToken cancellationToken = default(CancellationToken))

{

process.EnableRaisingEvents = true;

var taskCompletionSource = new TaskCompletionSource();

EventHandler handler = null;

handler = (sender, args) =>

{

process.Exited -= handler;

taskCompletionSource.TrySetResult(null);

};

process.Exited += handler;

if (cancellationToken != default(CancellationToken))

{

cancellationToken.Register(

() =>

{

process.Exited -= handler;

taskCompletionSource.TrySetCanceled();

});

}

return taskCompletionSource.Task;

}

///

/// Reads the data from the specified data recieved event and writes it to the

/// .

///

/// Adds the event handler.

/// Removes the event handler.

/// The text writer.

/// The cancellation token.

/// A task representing the asynchronous operation.

public static Task ReadAsync(

this Action addHandler,

Action removeHandler,

TextWriter textWriter,

CancellationToken cancellationToken = default(CancellationToken))

{

var taskCompletionSource = new TaskCompletionSource();

DataReceivedEventHandler handler = null;

handler = new DataReceivedEventHandler(

(sender, e) =>

{

if (e.Data == null)

{

removeHandler(handler);

taskCompletionSource.TrySetResult(null);

}

else

{

textWriter.WriteLine(e.Data);

}

});

addHandler(handler);

if (cancellationToken != default(CancellationToken))

{

cancellationToken.Register(

() =>

{

removeHandler(handler);

taskCompletionSource.TrySetCanceled();

});

}

return taskCompletionSource.Task;

}

如果觉得《c# 备份oracle waitforexit()方法死锁 ProcessStartInfo挂在“WaitForExit”上?为什么?》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。