I found beneath code for execute some process without freezing UI. This code is executed when 'Start Work' button is pressed. And I think users would stop this work by 'Stop' button. So I found this article at MSDN.. https://msdn.microsoft.com/en-us/library/jj155759.aspx . But, It was hard that applying this CancellationToken
at this code.. Anyone can help this problem?
I use public static async Task<int> RunProcessAsync(string fileName, string args)
method only.
Code (From https://stackoverflow.com/a/31492250):
public static async Task<int> RunProcessAsync(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<int> RunProcessAsync(Process process)
{
var tcs = new TaskCompletionSource<int>();
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;
}
Usage :
var cancelToken = new CancellationTokenSource();
int returnCode = async RunProcessAsync("python.exe", "foo.py", cancelToken.Token);
if (cancelToken.IsCancellationRequested) { /* something */ }
When the start button clicked, it starts some python script. When script is running and user wants to stop it, user presses stop button. Then program executes below code.
cancelToken.Cancel();
Thank you very much for reading this question.
The simple answer is that you can just call process.Kill()
when the token is canceled:
cancellationToken.Register(() => process.Kill());
But there are two problems with this:
InvalidOperationException
.Dispose()
the CancellationTokenRegistration
returned from Register()
, and the CancellationTokenSource
is long-lived, you have a memory leak, since the registrations will stay in memory as long as the CancellationTokenSource
.Depending on your requirements, and your desire for clean code (even at the cost of complexity) it may be okay to ignore problem #2 and work around problem #1 by swallowing the exception in a catch
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With