标签: cancellation

如何暂停BackgroundWorker?或类似的东西

BackgroundWorker通过WebClient.DownloadString在循环内调用来使用a 来下载一些网站.我希望用户在下载内容时取消选项,所以CancelAsync每当我发现CancellationPending在循环中间打开时我都会打电话.

但是现在我注意到函数DownloadString有时会冻结,所以我决定使用DownloadStringAsync(所有这些都在创建的其他线程中BackgroundWorker).因为我不想通过在调用之后退出循环和函数来重写我的整个代码,所以在调用DownloadStringAsync之后我做了一个while循环,它什么也没做,只是检查一个变量bool Stop,我在DownloadStringCompleted事件处理程序时变为true 被叫或当用户请求取消操作时.

现在,奇怪的是它在调试版本上运行良好; 但是在第一个版本中,程序会在while循环中冻结,就好像它是主线程一样.

c# backgroundworker request-cancelling cancellation

8
推荐指数
1
解决办法
2100
查看次数

Java中的声学回声消除

我正在实现一个使用纯Java的VOIP应用程序.当用户不使用耳机时(主要是带有内置麦克风的笔记本电脑),会出现回声问题.

目前发生了什么

VOIP应用程序的细节只是Java媒体框架的简单数据.基本上,我想在将音频数据写入扬声器输出之前对音频数据执行一些数字信号处理.

  public synchronized void addAudioData(byte[] ayAudioData)
  {
    m_oBuffer.enqueue(ayAudioData);
    this.notify();
  }
Run Code Online (Sandbox Code Playgroud)

如您所见,音频数据到达并在缓冲区中排队.这是为了迎合狡猾的连接并允许不同的数据包大小.这也意味着在我将音频数据播放到扬声器线路之前,我可以访问任何花哨的DSP操作所需的音频数据.

我已经管理了一个可以工作的回声消除器,但它需要大量的交互式用户输入,我想要一个自动回声消除器.

手动回声消除器

public static byte[] removeEcho(int iDelaySamples, float fDecay, byte[] aySamples)
  {
    m_awDelayBuffer = new short[iDelaySamples];
    m_aySamples = new byte[aySamples.length];
    m_fDecay = (float) fDecay;
    System.out.println("Removing echo");
    m_iDelayIndex = 0;

    System.out.println("Sample length:\t" + aySamples.length);
    for (int i = 0; i < aySamples.length; i += 2)
    {
      // update the sample
      short wOldSample = getSample(aySamples, i);

      // remove the echo
      short wNewSample = (short) (wOldSample - fDecay * m_awDelayBuffer[m_iDelayIndex]); …
Run Code Online (Sandbox Code Playgroud)

java signal-processing javasound echo cancellation

8
推荐指数
2
解决办法
9269
查看次数

如何在BlockingCollection上取消GetConsumingEnumerable()

在下面的代码中,我使用CancellationToken在生产者没有生成时唤醒GetConsumingEnumerable(),我想要脱离foreach并退出Task.但我没有看到IsCancellationRequested被记录,我的Task.Wait(timeOut)等待整个timeOut期间.我究竟做错了什么?

userToken.Task = Task.Factory.StartNew(state =>
{
    userToken.CancelToken = new CancellationTokenSource();

    foreach (var broadcast in userToken.BroadcastQueue.GetConsumingEnumerable(userToken.CancelToken.Token))
    {
        if (userToken.CancelToken.IsCancellationRequested)
        {
            Log.Write("BroadcastQueue IsCancellationRequested");
            break;
            ...
        }
    }

    return 0;
}, "TaskSubscribe", TaskCreationOptions.LongRunning);
Run Code Online (Sandbox Code Playgroud)

后来...

UserToken.CancelToken.Cancel();          
try
{
    task.Wait(timeOut);
}
catch (AggregateException ar)
{
    Log.Write("AggregateException " + ar.InnerException, MsgType.InfoMsg);
}
catch (OperationCanceledException)
{
    Log.Write("BroadcastQueue Cancelled", MsgType.InfoMsg);
}
Run Code Online (Sandbox Code Playgroud)

c# cancellation blockingcollection

8
推荐指数
2
解决办法
7919
查看次数

退出/取消跨线程循环的技术:bool,ManualResetEvent或CancellationToken

我正在编写一个包含几个线程的程序,每个程序都有一个while循环,直到用户指定它应该停止.我想到了退出循环的几种方法,以及随后的线程,并在下面概述了这些方法.

问题

  1. 每个都有利弊吗?
  2. 是否有使用一个而不是另一个的情况?
  3. 我听说过一些人说他们更喜欢CancellationTokens退出线程.对于其他两种方法,这种方法有什么吸引力呢?

以下是方法.

bool方法

最初,我已经声明了一个bool并且刚刚声明循环运行直到用户将bool设置为false : while(running) { Thread.Sleep(10); /*do work*/ }. 然后我思索是否完全是线程安全的.如果编译器进行了一些优化并将bool移动到寄存器,该怎么办?在这种情况下,线程会看到bool的不同值.因此,我使用volatile关键字标记bool 以避免编译器优化.

ManualResetEvent方法

我的下一个方法是创建一个ManualResetEvent,并且只是说,当WaitOne()为false时bool运行:while(!mre.WaitOne(10)) {/*do work*/}.这将阻塞10ms,然后一遍又一遍地运行循环,直到我们这样做mre.Set()并且循环退出.

CancellationToken方法

我还没有尝试过这种方法,但是我读了几个人们喜欢用这种方式取消线程的地方.它显然是线程安全的.可以定义一个CancellationTokenSource,调用它cts,然后传递cts.Token给新线程运行的方法,并使用if语句检查是否已请求取消:while(!token.IsCancellationRequested) { Thread.Sleep(10); /*do work*/ }

更新1:

我发现了一篇类似的帖子,得出的结论是该MRE方法明显慢于该CancellationToken方法.有关完整信息,请参阅此处:停止线程,ManualResetEvent,volatile boolean或cancellationToken

更新2:

当谈到将这种bool方法与其他两种方法进行比较时,Eric Lippert在这里有一个很好的答案:AutoResetEvent vs. boolean来阻止一个线程

更新3:

我找到了另一条相关的信息.取消取消后,取消权限无法重置.因此,当您只想暂时取消循环,以后再次启动它时,它并不理想.为此,MRE可能会更好(因为您可以根据自己的内容设置和重置).

c# multithreading manualresetevent cancellation cancellation-token

8
推荐指数
1
解决办法
2675
查看次数

Task.Delay没有被取消?

我正在尝试为游戏构建界面.游戏运行1分钟.该GetStop方法后60秒游戏停止.该游戏方法在游戏开始时和退出方法退出游戏.理想情况下,我想要的是当我在30秒后退出游戏时,计时器应该重置,点击"播放"按钮,计时器应该再次运行1分钟.这样下一场比赛就可以运行1分钟.如果我再次按退出按钮,则应重置计时器以进行下一场比赛.

但是,我的代码中似乎存在某个问题.每当我执行quit方法时,计时器似乎都保存在该状态.所以,如果我在30秒内退出比赛,那么下一场比赛将持续30秒.如果我在50秒内退出比赛,下一场比赛将只持续10秒.理想情况下,计时器应该重置但不会重置.

我在这里没有想法.任何人都可以提供一些建议?

private async Task GetStop(CancellationToken token)
{ 
    await Task.Run(async () =>
    {
        token.ThrowIfCancellationRequested();
        await Task.Delay(TimeSpan.FromSeconds(60), token);

        token.ThrowIfCancellationRequested();
        if (!token.IsCancellationRequested)
        {
            sendMessage((byte)ACMessage.AC_ESCAPE); 
        }
    }, token);
}

public async void Play()
{         
        sendMessage((byte)ACMessage.AC_START_RACE); 
        _cts.Cancel();

        if (_cts != null)
        {
            _cts.Dispose();
            _cts = null;
        }
        _cts = new CancellationTokenSource(); 
        await GetStop(_cts.Token);
   }

public void Quit()
{
        _cts.Cancel();
        if (_cts != null)
        {
            _cts.Dispose();
            _cts = null;
        }
    //
}
Run Code Online (Sandbox Code Playgroud)

c# task-parallel-library cancellation cancellationtokensource

8
推荐指数
1
解决办法
285
查看次数

Snakemake 在集群(slurm)取消作业时挂起

也许答案对许多人来说是显而易见的,但我很惊讶我找不到关于这个主题的问题,这对我来说是一个主要问题。我将不胜感激提示!

在由 slurm 管理的集群上提交作业时,如果队列管理器取消作业(例如,资源或时间不足),snakemake 似乎没有收到任何信号,并且永远挂起。另一方面,当作业失败时,snakemake 也会失败,正如预期的那样。这种行为是正常的/想要的吗?当工作被取消时,我怎么能让蛇制作失败?我在 3.13.3 版中遇到了这个问题,它仍然更新到 5.3.0。

例如,在这种情况下,我启动了一个简单的管道,但没有足够的资源用于规则 pluto:

$ snakemake -j1 -p --cluster 'sbatch --mem {resources.mem}' pluto.txt
Building DAG of jobs...
Using shell: /usr/bin/bash
Provided cluster nodes: 1
Unlimited resources: mem
Job counts:
    count   jobs
    1       pippo
    1       pluto
    2

[Tue Sep 25 16:04:21 2018]
rule pippo:
    output: pippo.txt
    jobid: 1
    resources: mem=1000

seq 1000000 | shuf > pippo.txt
Submitted job 1 with external jobid 'Submitted batch job 4776582'.
[Tue Sep 25 16:04:31 2018]
Finished job 1. …
Run Code Online (Sandbox Code Playgroud)

jobs cancellation slurm snakemake

8
推荐指数
1
解决办法
743
查看次数

如何在Node.js中正确取消http请求?

我需要在Node.js中实现可取消的客户端HTTP请求,而不使用外部库。我给一个Promise对象- cancellationPromise当外部请求取消时,该对象被拒绝。这就是我知道我可能需要打电话的方式request.abort()

问题是,request.abort()仅在https.request仍处于挂起状态并且response对象尚不可用时,才应该调用吗?

或者,即使我已经有了response对象并正在处理响应数据,也应该像下面的代码中那样调用它吗?在这种情况下,这会阻止更多response.on('data')事件发生吗?

  async simpleHttpRequest(url, oauthToken, cancellationPromise) {
    let cancelled = null;
    let oncancel = null;

    cancellationPromise.catch(error => { 
      cancelled = error; oncancel && oncancel(error) });

    try {
      const response = await new Promise((resolve, reject) => {
        const request = https.request(
          url.toString(), 
          { 
            method: 'GET', 
            headers: { 'Authorization': `Bearer ${oauthToken}` }        
          }, 
          resolve);

        oncancel = error => request.abort();
        request.on('error', reject);
        request.end();
      });

      if (cancelled) …
Run Code Online (Sandbox Code Playgroud)

javascript httprequest node.js cancellation

8
推荐指数
1
解决办法
261
查看次数

实现扩展方法WebRequest.GetResponseAsync并支持CancellationToken

这里的想法很简单,但实现有一些有趣的细微差别.这是我想在.NET 4中实现的扩展方法的签名.

public static Task<WebResponse> GetResponseAsync(this WebRequest request, CancellationToken token);
Run Code Online (Sandbox Code Playgroud)

这是我的初步实施.根据我的阅读,由于超时,可能需要取消 Web请求.除了该页面上描述的支持之外,request.Abort()如果通过该请求取消,我想要正确调用CancellationToken.

public static Task<WebResponse> GetResponseAsync(this WebRequest request, CancellationToken token)
{
    if (request == null)
        throw new ArgumentNullException("request");

    return Task.Factory.FromAsync<WebRequest, CancellationToken, WebResponse>(BeginGetResponse, request.EndGetResponse, request, token, null);
}

private static IAsyncResult BeginGetResponse(WebRequest request, CancellationToken token, AsyncCallback callback, object state)
{
    IAsyncResult asyncResult = request.BeginGetResponse(callback, state);
    if (!asyncResult.IsCompleted)
    {
        if (request.Timeout != Timeout.Infinite)
            ThreadPool.RegisterWaitForSingleObject(asyncResult.AsyncWaitHandle, WebRequestTimeoutCallback, request, request.Timeout, true);
        if (token != CancellationToken.None)
            ThreadPool.RegisterWaitForSingleObject(token.WaitHandle, …
Run Code Online (Sandbox Code Playgroud)

.net asynchronous httpwebrequest task-parallel-library cancellation

7
推荐指数
1
解决办法
2890
查看次数

在 ASP.NET MVC 中通过 CancellationToken 中止 AJAX 请求

我有一个与外部资源交互的 ASP.NET MVC 应用程序,并且有一个操作需要很多时间。所以在控制器中我有这样的方法

[HttpPost]
public async Task<JsonResult> SomeMethod(..., CancellationToken token)
{
    await _someService.ExecuteSlowOperationAsync(..., token);
    ...
}
Run Code Online (Sandbox Code Playgroud)

这个缓慢的操作看起来像

public async Task ExecuteSlowOperationAsync(..., CancellationToken token)
{
    return await Task.Run(() => 
    {
       //interacting with external resource
    }, token);
} 
Run Code Online (Sandbox Code Playgroud)

此方法与模态视图相关联,如果请求将花费太多时间,用户可能会决定关闭它。据此,我必须在不等待结果的情况下取消请求,因此在客户端我有类似的代码

...
var request = $.ajax(...);

...

$('#modal').on('hidden.bs.modal', function () {
  request.abort();
});
Run Code Online (Sandbox Code Playgroud)

如果我正确理解这篇文章,取消令牌通过框架模型绑定器与请求绑定,无需对其进行任何操作。当用户关闭模态表单时,在浏览器控制台中,我可以看到请求状态“已取消”,但在服务器端缓慢的操作仍在执行。Aslo我试过

CancellationToken disconnectedToken = Response.ClientDisconnectedToken;            
var source = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken, disconnectedToken);
Run Code Online (Sandbox Code Playgroud)

然后从这个来源拿了令牌,但还是一无所获。

我觉得我错过了一些重要的事情并且对这种情况有误解。任何想法如何使它工作?

c# asp.net-mvc asp.net-ajax task-parallel-library cancellation

7
推荐指数
1
解决办法
1118
查看次数

如何创建分层 CancellationTokenSource?

在我们的项目中,我们决定借助CancellationToken.

由于项目中作品的结构,我需要一个分层取消机制。通过分层,我的意思是父源取消会导致所有子源被递归取消,但子源取消不会传播到父源。

.NET 中是否有开箱即用的此类选项?如果没有,我不确定向父令牌注册委托是否足够,或者应该进一步考虑。

c# task task-parallel-library cancellation

7
推荐指数
2
解决办法
535
查看次数