我正在寻找除了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
什么是睡了一定的时间,但能够被一个中断的最佳方式IsCancellationRequested
从CancellationToken
?
我正在寻找一个适用于.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) 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
我开始一项任务,开始其他任务等等.
给定该树,如果任何任务失败,则整个操作的结果是无用的.我正在考虑使用取消令牌.令我惊讶的是,令牌没有"CancelThisToken()"方法......
所以我的问题是:我怎么能只拥有一个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
我使用传递的取消令牌,以便可以干净地关闭我的服务.该服务具有不断尝试连接到其他服务的逻辑,因此令牌是打破在单独线程中运行的这些重试循环的好方法.我的问题是我需要调用一个具有内部重试逻辑的服务,但是如果重试失败则在一段时间后返回.我想创建一个带有超时的新取消令牌,这将为我做到这一点.这个问题是我的新令牌没有链接到"主"令牌,所以当主令牌被取消时,我的新令牌仍然有效,直到它超时或建立连接并返回.我想要做的是将两个令牌链接在一起,这样当主要的一个被取消时,我的新一个也会取消.我尝试使用该CancellationTokenSource.CreateLinkedTokenSource
方法但是当我的新令牌超时时,它也取消了主令牌.有没有办法做我需要做的令牌,或者它需要更改重试逻辑(可能不会轻易做到这一点)
这是我想要做的:
主令牌 - 传递各种功能,以便服务可以干净地关闭.临时令牌 - 传递给单个函数并在一分钟后设置为超时
如果取消主令牌,则还必须取消临时令牌.
当临时令牌到期时,它不得取消主令牌.
给出以下代码:
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.IsCancellationRequested
是true
在catch块内,但事实并非如此.我误会了什么吗?
.net c# async-await cancellationtokensource dotnet-httpclient
我使用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) 我有这样的代码(在这里简化)等待完成任务:
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
我试图延迟在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
c# ×9
.net ×5
async-await ×3
asynchronous ×3
.net-4.0 ×1
cancellation ×1
debugging ×1
sleep ×1
winforms ×1