标签: cancellationtokensource

为什么CancellationToken与CancellationTokenSource是分开的?

我正在寻找除了CancellationTokenSource类之外还引入.NET CancellationToken结构的原因.我的理解是如何的API被使用,但想也明白为什么它就是这样设计的.

即,我们为什么要:

var cts = new CancellationTokenSource();
SomeCancellableOperation(cts.Token);

...
public void SomeCancellableOperation(CancellationToken token) {
    ...
    token.ThrowIfCancellationRequested();
    ...
}
Run Code Online (Sandbox Code Playgroud)

而不是直接传递CancellationTokenSource,如:

var cts = new CancellationTokenSource();
SomeCancellableOperation(cts);

...
public void SomeCancellableOperation(CancellationTokenSource cts) {
    ...
    cts.ThrowIfCancellationRequested();
    ...
}
Run Code Online (Sandbox Code Playgroud)

这是一个基于以下事实的性能优化:取消状态检查比传递令牌更频繁吗?

因此CancellationTokenSource可以跟踪和更新CancellationTokens,并且对于每个令牌,取消检查是本地字段访问?

鉴于两种情况下没有锁定的挥发性bool就足够了,我仍然无法理解为什么会更快.

谢谢!

.net multithreading task-parallel-library cancellationtokensource cancellation-token

119
推荐指数
4
解决办法
2万
查看次数

如何在.NET 4.0中请求超时或取消之前"休眠"

什么是睡了一定的时间,但能够被一个中断的最佳方式IsCancellationRequestedCancellationToken

我正在寻找一个适用于.NET 4.0的解决方案.

我想写

void MyFunc (CancellationToken ct)
{
   //... 
   // simulate some long lasting operation that should be cancelable 
   Thread.Sleep(TimeSpan.FromMilliseconds(10000), ct); 
}
Run Code Online (Sandbox Code Playgroud)

c# sleep .net-4.0 cancellation cancellationtokensource

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

如何正确重置CancellationToken?

async ctp今天早上我一直在玩,并有一个简单的程序与a button和a label.点击button它开始更新label,停止button它停止写入label.但是,我不确定如何重置,CancellationTokenSource以便我可以重新启动该过程.我的代码如下:

public partial class MainWindow : Window
{
    CancellationTokenSource cts = new CancellationTokenSource();
    public MainWindow()
    {
        InitializeComponent();
        button.Content = "Start";
    }

    async Task DoWork(CancellationToken cancelToken)
    {
        int i = 0;
        while (!cancelToken.IsCancellationRequested)
        {
            label.Content = i++.ToString();
            await TaskEx.Delay(50, cancelToken);
        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (button.Content == "Start")
        {
            button.Content = "Stop";
            DoWork(cts.Token);
        }
        else
        {
            button.Content = "Start";
            cts.Cancel(); …
Run Code Online (Sandbox Code Playgroud)

c# asynchronous async-await cancellationtokensource cancellation-token

41
推荐指数
3
解决办法
2万
查看次数

如何取消CancellationToken

我开始一项任务,开始其他任务等等.
给定该树,如果任何任务失败,则整个操作的结果是无用的.我正在考虑使用取消令牌.令我惊讶的是,令牌没有"CancelThisToken()"方法......

所以我的问题是:我怎么能拥有一个CancellationToken取消它呢?

c# task-parallel-library cancellationtokensource

38
推荐指数
3
解决办法
3万
查看次数

在Task.Run中使用CancellationToken超时不起作用

好的,我的问题非常简单.为什么这段代码不会抛出TaskCancelledException

static void Main()
{
    var v = Task.Run(() =>
    {
        Thread.Sleep(1000);
        return 10;
    }, new CancellationTokenSource(500).Token).Result;

    Console.WriteLine(v); // this outputs 10 - instead of throwing error.
    Console.Read();
}
Run Code Online (Sandbox Code Playgroud)

但这一个有效

static void Main()
{
    var v = Task.Run(() =>
    {
        Thread.Sleep(1000);
        return 10;
    }, new CancellationToken(true).Token).Result;

    Console.WriteLine(v); // this one throws
    Console.Read();
}
Run Code Online (Sandbox Code Playgroud)

.net c# task-parallel-library cancellationtokensource cancellation-token

32
推荐指数
4
解决办法
4万
查看次数

链接取消令牌

我使用传递的取消令牌,以便可以干净地关闭我的服务.该服务具有不断尝试连接到其他服务的逻辑,因此令牌是打破在单独线程中运行的这些重试循环的好方法.我的问题是我需要调用一个具有内部重试逻辑的服务,但是如果重试失败则在一段时间后返回.我想创建一个带有超时的新取消令牌,这将为我做到这一点.这个问题是我的新令牌没有链接到"主"令牌,所以当主令牌被取消时,我的新令牌仍然有效,直到它超时或建立连接并返回.我想要做的是将两个令牌链接在一起,这样当主要的一个被取消时,我的新一个也会取消.我尝试使用该CancellationTokenSource.CreateLinkedTokenSource方法但是当我的新令牌超时时,它也取消了主令牌.有没有办法做我需要做的令牌,或者它需要更改重试逻辑(可能不会轻易做到这一点)

这是我想要做的:

主令牌 - 传递各种功能,以便服务可以干净地关闭.临时令牌 - 传递给单个函数并在一分钟后设置为超时

如果取消主令牌,则还必须取消临时令牌.

当临时令牌到期时,它不得取消主令牌.

.net c# cancellationtokensource cancellation-token

32
推荐指数
4
解决办法
8598
查看次数

取消HttpClient请求 - 为什么TaskCanceledException.CancellationToken.IsCancellationRequested为false?

给出以下代码:

var cts = new CancellationTokenSource();

try 
{
    // get a "hot" task
    var task = new HttpClient().GetAsync("http://www.google.com", cts.Token);

    // request cancellation
    cts.Cancel();

    await task;

    // pass:
    Assert.Fail("expected TaskCanceledException to be thrown");
}
catch (TaskCanceledException ex) 
{
    // pass:
    Assert.IsTrue(cts.Token.IsCancellationRequested,
        "expected cancellation requested on original token");

    // fail:
    Assert.IsTrue(ex.CancellationToken.IsCancellationRequested,
        "expected cancellation requested on token attached to exception");
}
Run Code Online (Sandbox Code Playgroud)

我希望ex.CancellationToken.IsCancellationRequestedtrue在catch块内,但事实并非如此.我误会了什么吗?

.net c# async-await cancellationtokensource dotnet-httpclient

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

如何重置CancellationTokenSource并使用VS2010调试多线程?

我使用CancellationTokenSource来提供一个函数,以便用户可以取消冗长的操作.但是,在用户应用第一次取消后,后面的进一步操作不再起作用.我的猜测是CancellationTokenSource的状态已设置为Cancel,我想知道如何重置它.

  • 问题1:如何在首次使用后重置CancellationTokenSource?

  • 问题2:如何在VS2010中调试多线程?如果我在调试模式下运行应用程序,我可以看到该语句的以下异常

    this.Text = string.Format("Processing {0} on thread {1}", filename, Thread.CurrentThread.ManagedThreadId);
    
    Run Code Online (Sandbox Code Playgroud)

用户代码未处理InvalidOperaationException跨线程操作无效:控制从其创建的线程以外的线程访问的"MainForm".

谢谢.

private CancellationTokenSource cancelToken = new CancellationTokenSource();

private void button1_Click(object sender, EventArgs e)
{
    Task.Factory.StartNew( () =>
    {
        ProcessFilesThree();
    });
}

private void ProcessFilesThree()
{
    ParallelOptions parOpts = new ParallelOptions();
    parOpts.CancellationToken = cancelToken.Token;
    parOpts.MaxDegreeOfParallelism = System.Environment.ProcessorCount;

    string[] files = Directory.GetFiles(@"C:\temp\In", "*.jpg", SearchOption.AllDirectories);
    string newDir = @"C:\temp\Out\";
    Directory.CreateDirectory(newDir);

    try
    {
        Parallel.ForEach(files, parOpts, (currentFile) =>
        {
            parOpts.CancellationToken.ThrowIfCancellationRequested();

            string filename = Path.GetFileName(currentFile);

            using (Bitmap bitmap = new Bitmap(currentFile))
            {
                bitmap.RotateFlip(RotateFlipType.Rotate180FlipNone); …
Run Code Online (Sandbox Code Playgroud)

.net c# debugging winforms cancellationtokensource

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

如何组合TaskCompletionSource和CancellationTokenSource?

我有这样的代码(在这里简化)等待完成任务:

var task_completion_source = new TaskCompletionSource<bool>();
observable.Subscribe(b => 
   { 
      if (b) 
          task_completion_source.SetResult(true); 
   });
await task_completion_source.Task;    
Run Code Online (Sandbox Code Playgroud)

这个想法是订阅并等待true布尔流.这完成了"任务",我可以继续前进await.

但是我想取消 - 但不是订阅,而是等待.我想传递取消令牌(不知何故),task_completion_source所以当我取消令牌源时,await将继续前进.

怎么做?

更新:CancellationTokenSource这个代码是外部的,我这里所有的都是来自它的令牌.

c# asynchronous async-await cancellationtokensource taskcompletionsource

17
推荐指数
2
解决办法
7617
查看次数

在键盘事件中使用CancellationToken调用Task.Delay时的TaskCanceledException

我试图延迟在WinRT中从键盘事件调用的方法(在示例中为SubmitQuery())的处理,直到一段时间内没有其他事件(在这种情况下为500毫秒).

我只想在我认为用户输入完成后运行SubmitQuery().

使用下面的代码,当Task.Delay(500,cancellationToken.Token)时,我不断收到System.Threading.Tasks.TaskCanceledException; 叫做.我在这做错了什么?

CancellationTokenSource cancellationToken = new CancellationTokenSource();

private async void SearchBox_QueryChanged(SearchBox sender, SearchBoxQueryChangedEventArgs args)
{

        cancellationToken.Cancel();
        cancellationToken = new CancellationTokenSource();

    await Task.Delay(500, cancellationToken.Token);

    if (!cancellationToken.IsCancellationRequested)
    {
        await ViewModel.SubmitQuery();
    }
}
Run Code Online (Sandbox Code Playgroud)

c# asynchronous cancellationtokensource windows-runtime cancellation-token

16
推荐指数
4
解决办法
8084
查看次数