标签: cancellation

正确处理任务取消的一般方法

我正在进行代码审查,我担心这种模式,在该代码中随处可见:

try
{
    await DoSomethingAsync();
    await DoSomethingElseAsync();
    // and so on...
}
catch (OperationCanceledException)
{
    // all good, user cancelled
    // log and return
    return;
}
// handle other particular exceptions
// ...
catch (Exception ex)
{
    // fatal error, alert the user
    FatalErrorMessage(ex);
}
Run Code Online (Sandbox Code Playgroud)

我关心的部分是处理OperationCanceledException。这段代码不应该也处理AggregateException和检查唯一的内部异常吗OperationCanceledException

我知道Task.Wait或者Task.Result会抛出AggregateException这样的,而不是OperationCanceledException. 代码的作者向我保证她只使用async/awaitinside out 而从不使用Wait/Result. AggregateException因此,她不喜欢额外观察取消的想法。然而,我的观点是一些基于标准的TaskBCL API 仍然可以用 包装OperationCanceledExceptionAggregateException …

.net c# task-parallel-library cancellation async-await

3
推荐指数
1
解决办法
355
查看次数

为什么`asyncio.run()` 在 Python 3.8 中永远不会返回?

我的应用程序具有以下顶级代码(略有缩写):

def main():
    # Some setup code ...
    try:
        asyncio.run(my_coroutine())
    except Exception as e:
        print("Exiting due to exception {}: {}".format(type(e).__name__, e))
    print("Coroutine finished")
    # Some cleanup code ...
    print("Shutdown complete")
Run Code Online (Sandbox Code Playgroud)

在 Python 3.8 中asyncio.run永远不会完成,因此清理代码不会运行(并且不会打印关闭文本)。当应用程序应该退出时,它只是永远挂起。在 Python 3.7 中它运行良好。Python的3.6没有asyncio.run,但相当类似的代码loop.run_until_complete()loop.close()工作过。

一些额外的上下文:设置和清理代码启动并优雅地退出使用threading.Thread. 正是这个线程实际上停止了主协程:它取消了协程(从技术上讲,它取消了在 内调用的另一个协程my_coroutine()loop.call_soon_threadsafe

python exception cancellation python-asyncio

3
推荐指数
1
解决办法
687
查看次数

在这里抑制 `asyncio.CancelledError` 可以接受吗?

例子:

    with suppress(asyncio.CancelledError):
        [await t for t in asyncio.all_tasks(loop=self.loop)
            if t is not asyncio.current_task()]
Run Code Online (Sandbox Code Playgroud)

为了避免Task was destroyed but it is pending!警告,我必须在取消后等待任务,但等待它们会导致终端被垃圾邮件发送CancelledError。我知道它被取消了,但我不需要看到它。

使用contextlib.suppress此处会对取消产生负面影响吗?我可以避免看到取消的错误(或任务被破坏的警告而无需等待)的唯一其他方法是使用asyncio.wait而不是启动我的初始任务asyncio.gather。由于某种原因,wait似乎抑制了异常。我用了return_when=asyncio.FIRST_EXCEPTION一个waitreturn_exceptions=True一个gather。但似乎无论我如何设置它们的关键字参数,都会打印异常,而不会gather打印异常。wait

python task cancellation python-asyncio graceful-shutdown

3
推荐指数
1
解决办法
2721
查看次数

Android回音取消

我正在尝试使用android api中的AudioRecord类开发一个音频捕获应用程序,设置,如何使用MediaRecorder.AudioSource.MIC音频源,该应用程序可以工作,但是当我尝试使用回音消除时,设置一个MediaRecorder.AudioSource. VOICE_COMMUNICATION如何在创建AudioRecorder对象时抛出IllegalArgumentException,但我不知道为什么:

我的代码是:

private static final int SAMPLE_RATE = 16000;
private static final int BIT_ENCODING = AudioFormat.ENCODING_PCM_16BIT;
private static final int CHANNEL_CONFIGURATION = AudioFormat.CHANNEL_CONFIGURATION_MONO;

private int m_i32BufferSize;

private AudioRecord m_AudioRecorder;

public caudioCapture ()
{
    super ();

    m_i32BufferSize = AudioRecord.getMinBufferSize(SAMPLE_RATE, CHANNEL_CONFIGURATION, BIT_ENCODING);

    //Create audio recorder object 
    try
    {
        m_AudioRecorder = new AudioRecord (MediaRecorder.AudioSource.VOICE_COMMUNICATION,SAMPLE_RATE,CHANNEL_CONFIGURATION,BIT_ENCODING,m_i32BufferSize);

    }
    catch (IllegalArgumentException e)
    {
        throw new IllegalArgumentException("Bad arguments on AudioRecorder creation", e);
    }
Run Code Online (Sandbox Code Playgroud)

在我的Android清单中,我有:

uses-permission android:name ="android.permission.RECORD_AUDIO"

也许是因为我使用的是三星galaxy tab p1000并且它与Android 2.2一起运行?任何的想法?

非常感谢

audio android echo cancellation

2
推荐指数
1
解决办法
9343
查看次数

什么时候POSIX线程取消不立即?

POSIX为线程取消类型指定了两种类型:PTHREAD_CANCEL_ASYNCHRONOUSPTHREAD_CANCEL_DEFERRED(设置pthread_setcanceltype(3))确定何时pthread_cancel(3)生效.通过我的阅读,POSIX手册页对这些内容并没有太多说明,但Linux手册页中有以下内容PTHREAD_CANCEL_ASYNCHRONOUS:

线程可以随时取消.(通常,它会在收到取消请求后立即取消,但系统不保证这一点.)

我很好奇系统的含义并不能保证这一点.我可以很容易地想象这种情况发生在多核/多CPU系统中(在上下文切换之前).但是单核系统呢:

  1. 请求取消并启用取消(pthread_setcancelstate(3))并取消类型设置为PTHREAD_CANCEL_ASYNCHRONOUS?时,我们是否可以立即取消线程?
  2. 如果是的话,在什么条件下会发生这种情况?

我主要对Linux(LinuxThreads/NPTL)感到好奇,但更普遍的是关于POSIX标准兼容的查看此取消业务的方式.

更新/澄清:这里真正的实际问题是在调用pthread_cancel()目标线程已启用取消并设置为键入的位置后立即销毁的资源的使用PTHREAD_CANCEL_ASYNCHRONOUS!所以关键在于:在这种情况下取​​消的线程是否有一个很小的可能性在上下文切换后继续正常运行(即使是很短的时间)?

感谢Damon的回答,减少了与下一个上下文切换相关的信号传递和处理问题.

更新2:我回答了我自己的问题,指出这是一个不好的问题,并且应该从根本上不同的概念层面解决基础程序设计.我希望这个"错误"的问题对于那些想知道异步取消的奥秘的人有用.

linux signals pthreads cancellation

2
推荐指数
1
解决办法
967
查看次数

从任务正文内部取消任务

我读到了取消方法,但根据我的理解,它们都提供了对任务外部任务的控制,但是如果我想从内部取消任务.

例如,在这个伪代码中:

Task tasks = new Task(() =>
{ 
     bool exists = CheckFromDB();
      if (!exists)
         break;
}
Run Code Online (Sandbox Code Playgroud)

我可以从内部取消任务吗?我得到的唯一想法是在任务中触发一个异常并从外部处理它,但是这不是一种方法.

.net c# winforms task-parallel-library cancellation

2
推荐指数
1
解决办法
1597
查看次数

已取消的任务也显示为已完成

我正在玩async-await和取消以获得更多关于此事的理解.为此,我做了以下控制台应用程序:

using System;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncTest
{
    class Program
    {
        private static CancellationTokenSource _cancellationTokenSource;
        private static CancellationToken _cancellationToken;

        static void Main(string[] args)
        {
            Console.CancelKeyPress += myHandler;

            _cancellationTokenSource = new CancellationTokenSource();
            _cancellationToken = _cancellationTokenSource.Token;

            var task = DoWorkAsync(_cancellationToken).ContinueWith(ContinueMethod);
            task.Wait();

            Console.ReadLine();
        }

        protected static void myHandler(object sender, ConsoleCancelEventArgs args)
        {
            if (_cancellationToken.CanBeCanceled)
            {
                _cancellationTokenSource.Cancel();
            }
            args.Cancel = true;
        }

        static void ContinueMethod(Task task)
        {
            if (task.IsCanceled)
            {
                Console.WriteLine("The task was canceled");
            }

            if (task.IsCompleted)
            {
                Console.WriteLine("The task completed successfully"); …
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library cancellation

2
推荐指数
1
解决办法
1262
查看次数

如何在 TPL 中处理任务取消

再会!我正在为 WinForms UI 编写一个帮助程序库。开始使用 TPL async/await 机制并遇到这种代码示例的问题:

    private SynchronizationContext _context;

    public void UpdateUI(Action action)
    {
        _context.Post(delegate { action(); }, null);
    }


    private async void button2_Click(object sender, EventArgs e)
    {

        var taskAwait = 4000;
        var progressRefresh = 200;
        var cancellationSource = new System.Threading.CancellationTokenSource();

        await Task.Run(() => { UpdateUI(() => { button2.Text = "Processing..."; }); });

        Action usefulWork = () =>
        {
            try
            {
                Thread.Sleep(taskAwait);
                cancellationSource.Cancel();
            }
            catch { }
        };
        Action progressUpdate = () =>
        {
            int i = 0;
            while …
Run Code Online (Sandbox Code Playgroud)

c# task task-parallel-library cancellation async-await

2
推荐指数
1
解决办法
1398
查看次数

如何在Qt/C++中可靠地杀死一个线程?

我正在制作一个桌面编程游戏,包括C++ 11,Qt 5.6(一旦V-Play支持它,很快就会有5.7)和QML.用户将能够编写任意代码来解决难题; 但是,代码应该完全沙箱化,并且不会导致应用程序其余部分出现问题.

所以我实例化了一个脚本引擎,它的环境我完全控制并通过它运行播放器的代码.我不会说什么脚本引擎,因为我不希望解决方案依赖于引擎(另外,我可能支持多种语言).当玩家点击"提交"时,我会异步运行脚本,以便游戏的其余部分仍然响应.

但这是我的问题:如果玩家的代码需要很长时间才能运行会发生什么?或者更糟糕的是,如果它是一个无限循环呢? 玩家在学习时犯错误,所以"他们不应该这样做" 在这里不是一个有效的答案.

所以我只是让玩家随意终止他们的代码,很好. 但是,如何在不冒未定义的行为,内存泄漏,崩溃或其他可能对游戏产生负面影响的事情的情况下做到这一点?

相关的是以下内容:

  • 解决方案应该是多平台的.
  • 该解决方案应该取决于我使用的是什么样的脚本引擎.
  • 我不是在线程之间传递数据,所以我不需要担心数据争用.
  • 返回的QFutures 支持.QtConcurrent::runQFuture::cancel

c++ qt multithreading cancellation

2
推荐指数
1
解决办法
194
查看次数

从线程本身中取消异步线程

有没有办法cancelasync异步包调用的线程中使用?我可以看到你可以从线程外部取消它,但我想知道是否有一个cancelSelf :: IO ()函数可以阻止它自己的执行.我可以使用唯一的id生成和线程引用的共享Map来组合一些东西Async,线程本身可以引用它,但这看起来太多了.我可以逃避未被捕获的异常或其他什么吗?

multithreading haskell asynchronous cancellation

2
推荐指数
1
解决办法
73
查看次数