我发现在代码下执行某些进程而没有冻结UI.按下"开始工作"按钮时执行此代码.我认为用户可以通过"停止"按钮停止这项工作.所以我在MSDN上发现了这篇文章.. https://msdn.microsoft.com/en-us/library/jj155759.aspx.但是,CancellationToken
在这段代码中应用这个很难.任何人都可以帮助解决这个问题吗?
我public static async Task
只使用方法.
代码(来自/sf/ask/17360801/):
public static async TaskRunProcessAsync(string fileName, string args) { using (var process = new Process { StartInfo = { FileName = fileName, Arguments = args, UseShellExecute = false, CreateNoWindow = true, RedirectStandardOutput = true, RedirectStandardError = true }, EnableRaisingEvents = true }) { return await RunProcessAsync(process).ConfigureAwait(false); } } // This method is used only for internal function call. private static Task RunProcessAsync(Process process) { var tcs = new TaskCompletionSource (); process.Exited += (s, ea) => tcs.SetResult(process.ExitCode); process.OutputDataReceived += (s, ea) => Console.WriteLine(ea.Data); process.ErrorDataReceived += (s, ea) => Console.WriteLine("ERR: " + ea.Data); bool started = process.Start(); if (!started) { //you may allow for the process to be re-used (started = false) //but I'm not sure about the guarantees of the Exited event in such a case throw new InvalidOperationException("Could not start process: " + process); } process.BeginOutputReadLine(); process.BeginErrorReadLine(); return tcs.Task; }
用法:
var cancelToken = new CancellationTokenSource(); int returnCode = async RunProcessAsync("python.exe", "foo.py", cancelToken.Token); if (cancelToken.IsCancellationRequested) { /* something */ }
单击开始按钮时,它会启动一些python脚本.当脚本运行并且用户想要停止它时,用户按下停止按钮.然后程序在代码下执行.
cancelToken.Cancel();
非常感谢你阅读这个问题.
简单的答案是,您可以在process.Kill()
取消令牌时调用:
cancellationToken.Register(() => process.Kill());
但是这有两个问题:
如果你试图杀死一个尚未存在或已经终止的进程,你会得到一个InvalidOperationException
.
如果你没有Dispose()
在CancellationTokenRegistration
从返回Register()
,和CancellationTokenSource
长寿命,你有内存泄漏,因为注册将保留在内存中,只要CancellationTokenSource
.
根据您的要求和您对清洁代码的需求(即使以复杂性为代价),可以忽略问题#2并通过吞下a中的异常来解决问题#1 catch
.