标签: cancellation

如何取消正在运行的任务?

我想取消正在运行的任务(当用户按下退出键时)。当我点击“escape”键 Form_KeyDown 运行但不取消任务时!

CancellationTokenSource tokenSource = new CancellationTokenSource();
CancellationToken token=new CancellationToken();

private async void Search_Button_ClickAsync(object sender, EventArgs e)
{
  token = tokenSource.Token;
  await (Task.Factory.StartNew(() =>
           {
             //...my program
           },
           token));

private void Form_KeyDown(object sender, KeyEventArgs e)
{
  if (e.KeyCode == Keys.Escape)
  {
    tokenSource.Cancel();
  }
}
Run Code Online (Sandbox Code Playgroud)

c# task cancellation cancellationtokensource cancellation-token

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

Async/Await等同于.ContinueWith和CancellationToken以及TaskScheduler.FromCurrentSynchronizationContext()调度程序

这是这个问题的后续行动.

问题:使用async/ await代替.ContinueWith()?表达以下内容的简洁方法是什么?:

var task = Task.Run(() => LongRunningAndMightThrow());

m_cts = new CancellationTokenSource();
CancellationToken ct = m_cts.Token;

var uiTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task updateUITask = task.ContinueWith(t => UpdateUI(t), ct, TaskContinuationOptions.None, uiTaskScheduler);
Run Code Online (Sandbox Code Playgroud)

我主要对UI SynchronizationContext(例如Winforms)的情况感兴趣

请注意,该行为具有以下所有期望的行为:

  1. CancellationToken取消时,updateUITask最终会尽快取消(即LongRunningAndMightThrow工作可能仍会持续相当长的一段时间).

  2. ct的CancellationToken被检查取消在UI线程上运行UpdateUI拉姆达之前(见这个答案).

  3. updateUITask最终会取消在某些情况下task完成的或者是错误的(因为ct的CancellationToken在执行UpdateUI拉姆达之前在UI线程检查.

  4. CancellationToken在UI线程的检查和UpdateUIlambda 的运行之间没有中断流.也就是说,如果CancellationTokenSource唯一曾经在UI线程上取消了,再有就是的检查之间不存在竞争条件CancellationToken和的运行UpdateUI拉姆达-没有什么可以触发CancellationToken这两个事件之间,因为UI线程不放弃这两个事件之间.

讨论:

  • 将其转换为异步/等待的主要目标之一是将UpdateUI …

c# task-parallel-library cancellation async-await

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

c#重置取消令牌

我有一些代码要运行,直到我请求取消为止。

              Task.Run(() =>
                {
                    while (!token.IsCancellationRequested)
                    {
                        GetFeedbackTask();
                    }
                }, token);
Run Code Online (Sandbox Code Playgroud)

然后我执行这个方法token.Cancel()。这将按预期取消任务,按预期取消我的 while 循环。问题是当我在取消token.IsCancellationRequested属性后再次尝试运行 Task 时true。是什么设置了属性false?我需要Dispose令牌吗?

c# task task-parallel-library cancellation

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

停止挂同步方法

XenAPI 中有一个方法HTTP_actions.put_import() ,它是同步的,并且支持通过其 delegate 取消

我有以下方法:

private void UploadImage(.., Func<bool> isTaskCancelled)
{
    try
    {
        HTTP_actions.put_import(
            cancellingDelegate: () => isTaskCancelled(),
            ...);
    }
    catch (HTTP.CancelledException exception)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,该方法HTTP_actions.put_import会挂起并且不会对isTaskCancelled(). 在这种情况下,整个应用程序也会挂起。

我可以在单独的线程中运行此方法,并在收到取消信号后强制终止它,但此方法并不总是挂起,有时我想优雅地取消此方法。只有当这个方法真的悬了的时候,我才想亲手杀死它。

处理这种情况的最佳方法是什么?

c# multithreading asynchronous task cancellation

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

立即任务取消

我有一个关于使用cancellationToken和cancellationTokenSource取消任务的问题:

通常的方法如下:

var cts = new CancellationTokenSource();
var t = Task.Run(() => {    
while(true)
  {
    if (!cts.IsCancellationRequested)   
     {  //do stuff }
  }
}, cts.Token);
Run Code Online (Sandbox Code Playgroud)

因此,while循环一直持续到请求令牌为止.今天,在研究Cancel()方法时,我发现你可以使用 Register()方法来定义在请求令牌时运行的其他代码,所以我想知道,如果有人写了这样的话:

var cts = new CancellationTokenSouce();
token=cts.Token;
token.Register(
() => {
//do something to manage the cancel call
return;
};
) 
var t = Task.Run(() => {
//do stuff 
}, cts.Token);
Run Code Online (Sandbox Code Playgroud)

通过这样做,与该关联的任务CancellationToken将立即停止执行,而不是像在通常的实现中那样必须完成当前的迭代.我的问题是:这是立即停止Task或有更好方法的正确方法吗?

.net c# task cancellation .net-standard

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

处理多个带有超时的CancellationToken

对于在以下情况下如何实现取消标记,我有些困惑。

说我有一个方法,它有一个取消令牌,没有指定超时,像这样。

public static async Task DoSomeAsyncThingAsync(CancellationToken cancellationToken = default)
{
    try
    {
        Task.Delay(1000, cancellationToken)
    }
    catch (OperationCanceledException canceledException)
    {
        // Do something with canceledException
        Console.WriteLine("DoSomeElseAsyncThingAsync {0}", canceledException);
        throw;
    }
    catch (Exception exception)
    {
        // Do something with exception
        Console.WriteLine("DoSomeElseAsyncThingAsync {0}", exception);
        throw;
    }
}
Run Code Online (Sandbox Code Playgroud)

但是在该方法中,我想调用另一个期望CancellationToken除此以外的方法,但这次我要对此设置超时。

public static async Task DoSomeAsyncThingAsync(CancellationToken cancellationToken = default)
{
    try
    {
        var innerCancellationTokenSource = new CancellationTokenSource();
        innerCancellationTokenSource.CancelAfter(1000);
        var innerCancellationToken = innerCancellationTokenSource.Token;

        await DoSomeElseAsyncThingAsync(innerCancellationToken);
    }
    catch (OperationCanceledException canceledException)
    {
        // Do something with …
Run Code Online (Sandbox Code Playgroud)

c# cancellation async-await cancellationtokensource cancellation-token

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

如果上下文被取消则终止函数执行

我当前的功能最初是不了解上下文的。

func (s *Service) ChunkUpload(r *multipart.Reader) error {
    chunk, err := s.parseChunk(r)
    if err != nil {
        return fmt.Errorf("failed parsing chunk %w", err)
    }

    if err := os.MkdirAll(chunk.UploadDir, 02750); err != nil {
        return err
    }

    if err := s.saveChunk(chunk); err != nil {
        return fmt.Errorf("failed saving chunk %w", err)
    }

    return nil
}
Run Code Online (Sandbox Code Playgroud)

我已经更新了它的方法调用,现在将 acontext.Context作为其第一个参数。我的主要目标是在上下文取消后立即终止并返回函数。

我最初的实现是这样的。

func (s *Service) ChunkUpload(ctx context.Context, r *multipart.Reader) error {
    errCh := make(chan error)

    go func() {
        chunk, err := s.parseChunk(r)
        if …
Run Code Online (Sandbox Code Playgroud)

channel go cancellation

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

C# 在 for 循环期间检查取消令牌

我不完全理解取消令牌,但我相信这是我需要使用的。

我有一个充满文件路径的列表框,以及一个方法 ( ProcesstListSort),它遍历列表框中的每个文件路径并根据文件类型执行不同的方法。ProcessListSort从另一个方法调用,即从按钮单击调用。我试图BeginEverything在后台任务中运行,因为它锁定了 UI。在这种情况下实现取消令牌检查的最佳位置是什么?

单击此按钮开始该过程:

public async void button1_Click(object sender, EventArgs e)
{
    Task task1 = new Task(BeginEverything);
    task1.Start();
    await task1;
}
Run Code Online (Sandbox Code Playgroud)

哪个启动这个:

public void BeginEverything()
{
    CreateThing1();
    CreateThing2();
    ProcessListSort();  //This is the one I think I need to interrupt because it's the longest
    CreateThing3();
    CreateThing4();
}
Run Code Online (Sandbox Code Playgroud)

在这里启动最长的任务(根据文件类型对文件进行排序和执行其他方法,将文件路径传递给其他方法):

public void ProcessListSort()
{
    for (int i = 0; i < listBox2.Items.Count; i++)
    {
        string p = listBox2.Items[i].ToString();
        FileAttributes attr = File.GetAttributes(p);

        if (p.EndsWith(".zip"))
        {
            Method1(p); …
Run Code Online (Sandbox Code Playgroud)

c# for-loop winforms cancellation cancellation-token

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

在 FromContinuations 中使用取消延续

我正在尝试async通过Async<'T>I create with了解工作流程Async.FromContinuations,但看不到如何使用取消延续。我正在尝试这个:

open System

let asyncComputation divisor =
    Async.FromContinuations
        (fun (success, except, cancel) ->
            try
                printfn "Going to sleep..."
                Threading.Thread.Sleep 3000
                printfn "...waking up"
                1 / divisor |> ignore
                printfn "Calling success continuation..."
                success ()
            with
            | :? OperationCanceledException as e ->
                printfn "Calling cancellation continuation..."
                cancel e
            | e ->
                printfn "Calling exception continuation..."
                except e)

[<EntryPoint>]
let main argv =
    use tokenSource = new Threading.CancellationTokenSource ()
    Async.Start (asyncComputation (int argv.[0]), tokenSource.Token) …
Run Code Online (Sandbox Code Playgroud)

continuations f# asynchronous cancellation

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

用取消方法增加ES6承诺

我正在尝试编写一些代码,这些代码在启动一些可能长时间运行的异步活动后返回ES6承诺.但是,我希望有可能取消该活动,所以我想用'取消'方法来增加我的承诺.

一个sscce说明了我想要做的是如下:

function TimerPromise(timeInterval) {
    var timer;

    var p = new Promise(
        function(resolve,reject) {
            timer = setTimeout(
                function() {
                    resolve(true);
                },
                timeInterval
            );
        }
    );

    p.cancel = function() {
        clearTimeout(timer);
    };

    console.log("p.cancel is ",p.cancel);

    return p;
}

var t = TimerPromise(2000).then(function(res) { console.log("Result is ",res); });

t.cancel();
Run Code Online (Sandbox Code Playgroud)

在示例中,TimerPromise只设置一个计时器来模拟长时间运行的异步活动.

这是我在运行时得到的:

$ node test.js
p.cancel is  function () {
                timer.clearTimeout();
        }
/home/harmic/js/src/test.js:28
t.cancel();
  ^

TypeError: t.cancel is not a function
    at Object.<anonymous> (/home/harmic/js/src/test.js:28:3)
    at Module._compile (module.js:413:34)
    at Object.Module._extensions..js (module.js:422:10)
    at …
Run Code Online (Sandbox Code Playgroud)

javascript node.js promise cancellation es6-promise

0
推荐指数
1
解决办法
399
查看次数

等待下载完成时取消 WebClient 下载

寻找一种更普遍接受的等待模式WebClient

  • 下载文件(可能需要几百毫秒或几分钟)
  • 等待下载完成后再执行任何其他工作
  • 定期检查另一个类的标志 (bool) 并根据需要取消下载(无法修改此类)

限制条件:

  • 不能使用 async/await 除非它是类似的Task.Run(async () => await method())
  • Download调用该方法时,它只需要像普通方法一样返回字符串
  • 可以使用 .Net 4.5 和 Roslyn 编译器的任何功能
  • 是否使用WebClient.DownloadFileTaskAsync或 都没有区别;DownloadFileAsync只需能够根据需要使用取消下载WebClient

当前的实现似乎有效,但似乎不太正确。是否有比使用while循环并在使用时Thread.Sleep定期检查更普遍可接受的替代方案?otherObject.ShouldCancelWebClient

private string Download(string url)
{
    // setup work
    string fileName = GenerateFileName();

    // download file
    using (var wc = new WebClient()) 
    {
        wc.DownloadFileCompleted += OnDownloadCompleted

        Task task = wc.DownloadFileTaskAsync(url, fileName);

        // Need to wait until either the download is completed …
Run Code Online (Sandbox Code Playgroud)

c# webclient cancellation

0
推荐指数
1
解决办法
2788
查看次数

如何取消 ValueTask&lt;T&gt;

我知道如何取消任务,但找不到有关如何向 ValueTask 方法添加取消的任何信息。通常我会取消这样的任务:

public async Task<int> Foo(
    CancellationToken cancellationToken)
{
    TaskCompletionSource<int> tcsCancel =
        new TaskCompletionSource<int>();

    cancellationToken.Register(() =>
    {
        tcsCancel.TrySetCanceled();
    });

    Task<int> task = LongOperation();

    var completedTask = await Task.WhenAny(
        tcsCancel.Task,
        task).ConfigureAwait(false);

    return await completedTask.ConfigureAwait(false);
}
Run Code Online (Sandbox Code Playgroud)

或者像这样:

if (cancellationToken.IsCancellationRequested)
    return Task.FromCanceled<int>(cancellationToken);
Run Code Online (Sandbox Code Playgroud)

事实是,ValueTask 既没有 FromCanceled 也没有 WhenAny。我是不是应该做...

cancellationToken.ThrowIfCancellationRequested();
Run Code Online (Sandbox Code Playgroud)

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

0
推荐指数
1
解决办法
805
查看次数

当客户端中止请求时,WebFlux 如何停止发布者?

SpringBoot v2.5.1

有一个端点请求长时间运行的进程结果,并且它是以某种方式创建的
(为简单起见,它是Mono.fromCallable( ... long running ... ).

客户端发出请求并触发发布者执行工作,但几秒钟后客户端中止请求(即连接丢失)。并且该过程仍然继续利用资源来计算丢弃的结果。

通知 Project Reactor 事件循环有关应取消的不必要的正在进行的工作的机制是什么?

@RestController 
class EndpointSpin {
 
  @GetMapping("/spin")
  Mono<Long> spin() {
    AtomicLong counter = new AtomicLong(0);
    Instant stopTime = Instant.now().plus(Duration.of(1, ChronoUnit.HOURS));

    return Mono.fromCallable(() -> {

      while (Instant.now().isBefore(stopTime)) {
        counter.incrementAndGet();

        if (counter.get() % 10_000_000 == 0) {
          System.out.println(counter.get());
        }

        // of course this does not work
        if (Thread.currentThread().isInterrupted()){
           break;
        }
      }

      return counter.get();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

java reactive-programming cancellation project-reactor spring-webflux

0
推荐指数
1
解决办法
1388
查看次数