我怎样才能通过的CancellationToken停止异步处理? [英] How can I stop async Process by CancellationToken?

查看:269
本文介绍了我怎样才能通过的CancellationToken停止异步处理?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现code的执行过程中的一些不结冰界面下方。这code在执行时开始工作按钮是pressed。我认为,用户会停止停止按钮,这项工作。所以,我发现这篇文章在MSDN .. https://msdn.microsoft.com/ EN-US /库/ jj155759.aspx 。但是,这是很难说将这种的CancellationToken 在这个code ..任何人都可以帮助这个问题?

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?

我用公共静态异步任务< INT> RunProcessAsync(字符串文件名,字符串参数)方法只。

code(从 http://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;
}

用法:

var cancelToken = new CancellationTokenSource();
int returnCode = async RunProcessAsync("python.exe", "foo.py", cancelToken.Token);
if (cancelToken.IsCancellationRequested) { /* something */ }

在启动按钮点击后,它开始一些Python脚本。
当脚本正在运行,用户想停止它,用户presses停止按钮。
然后,程序执行下面code。

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.

推荐答案

简单的答案是,你可以叫 process.Kill()当令牌被取消:

The simple answer is that you can just call process.Kill() when the token is canceled:

cancellationToken.Register(() => process.Kill());

但有两个问题:


  1. 如果你试图杀死一个过程中不存在或已经终止,你会得到一个出现InvalidOperationException

  2. 如果你不这样做的Dispose() CancellationTokenRegistration 返回寄存器() CancellationTokenSource 是长期存在的,你有内存泄漏,因为注册将长留在内存中的 CancellationTokenSource

  1. If you attempt to kill a process a doesn't exist yet or that has already terminated, you get an InvalidOperationException.
  2. If you don't 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.

根据您的要求,你的清洁code(即使在复杂的费用)的愿望可能是好的通过在<$ C $吞咽异常忽略的问题#2和变通问题#1 C>捉。

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.

这篇关于我怎样才能通过的CancellationToken停止异步处理?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆