我想取消正在运行的任务(当用户按下退出键时)。当我点击“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
这是这个问题的后续行动.
问题:使用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)的情况感兴趣
请注意,该行为具有以下所有期望的行为:
当CancellationToken取消时,updateUITask最终会尽快取消(即LongRunningAndMightThrow工作可能仍会持续相当长的一段时间).
该ct的CancellationToken被检查取消在UI线程上运行UpdateUI拉姆达之前(见这个答案).
该updateUITask最终会取消在某些情况下task完成的或者是错误的(因为ct的CancellationToken在执行UpdateUI拉姆达之前在UI线程检查.
CancellationToken在UI线程的检查和UpdateUIlambda 的运行之间没有中断流.也就是说,如果CancellationTokenSource是唯一曾经在UI线程上取消了,再有就是的检查之间不存在竞争条件CancellationToken和的运行UpdateUI拉姆达-没有什么可以触发CancellationToken这两个事件之间,因为UI线程不放弃这两个事件之间.
讨论:
将其转换为异步/等待的主要目标之一是将UpdateUI …
我有一些代码要运行,直到我请求取消为止。
Task.Run(() =>
{
while (!token.IsCancellationRequested)
{
GetFeedbackTask();
}
}, token);
Run Code Online (Sandbox Code Playgroud)
然后我执行这个方法token.Cancel()。这将按预期取消任务,按预期取消我的 while 循环。问题是当我在取消token.IsCancellationRequested属性后再次尝试运行 Task 时true。是什么设置了属性false?我需要Dispose令牌吗?
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(). 在这种情况下,整个应用程序也会挂起。
我可以在单独的线程中运行此方法,并在收到取消信号后强制终止它,但此方法并不总是挂起,有时我想优雅地取消此方法。只有当这个方法真的悬了的时候,我才想亲手杀死它。
处理这种情况的最佳方法是什么?
我有一个关于使用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或有更好方法的正确方法吗?
对于在以下情况下如何实现取消标记,我有些困惑。
说我有一个方法,它有一个取消令牌,没有指定超时,像这样。
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
我当前的功能最初是不了解上下文的。
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) 我不完全理解取消令牌,但我相信这是我需要使用的。
我有一个充满文件路径的列表框,以及一个方法 ( 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) 我正在尝试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) 我正在尝试编写一些代码,这些代码在启动一些可能长时间运行的异步活动后返回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) 寻找一种更普遍接受的等待模式WebClient:
限制条件:
Task.Run(async () => await method())Download调用该方法时,它只需要像普通方法一样返回字符串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) 我知道如何取消任务,但找不到有关如何向 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) 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
cancellation ×13
c# ×9
task ×4
async-await ×3
asynchronous ×2
.net ×1
.net-core ×1
channel ×1
es6-promise ×1
f# ×1
for-loop ×1
go ×1
java ×1
javascript ×1
node.js ×1
promise ×1
webclient ×1
winforms ×1