如何取消任务C#

编程入门 行业动态 更新时间:2024-10-26 16:28:06
本文介绍了如何取消任务C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个任务,可以从Web服务检索一些数据.仅当我打开页面(即Xamarin.Forms)时,Web服务才应被调用,并且仅当没有其他版本的任务正在运行时,Web服务才应运行-这部分工作正常.

I have a Task which retrieves some data from a Web Service. The Webservice should only get called when I open a page (this is Xamarin.Forms) and it should only run if there isn't another version of the task running - This part works fine.

当我离开页面时,我想取消任务-我似乎无法使该任务正常工作.当OnAppearing(),OnDisappearing(),OnAppearing() is hit before the webservice returns the data, logs just write "Task has attempted to start..." which means that the Task didn't get cancelled. Instead the task should have been cancelled when OnDisappearing()`被调用时.

When I move away from the page, I want to cancel the Task - I can't seem to get that piece working. When OnAppearing(), OnDisappearing(), OnAppearing() is hit before the webservice returns the data, logs just write "Task has attempted to start..." which means that the Task didn't get cancelled. Instead the task should have been cancelled whenOnDisappearing()` was called.

我尝试遵循在StackOverflow上发布的一些示例,但似乎无法正常工作,我无法弄清楚.

I have tried to follow some of the examples posted on StackOverflow but doesn't seem to work and I can't quite figure it out.

我的代码如下:

出现:

private Task task; CancellationTokenSource tokenSource = new CancellationTokenSource(); protected override void OnAppearing() { base.OnAppearing(); if (task != null && (task.Status == TaskStatus.Running || task.Status == TaskStatus.WaitingToRun || task.Status == TaskStatus.WaitingForActivation)) { Debug.WriteLine("Task has attempted to start while already running"); } else { Debug.WriteLine("Task has began"); var token = tokenSource.Token; task = Task.Run(async () => { await GetDataAsync(); /* EDIT: This is what I originally posted, but doesn't work so have commented it out while (!token.IsCancellationRequested) { await GetDataAsync(); } */ }, token); } }

消失中:

protected override void OnDisappearing() { base.OnDisappearing(); Debug.WriteLine("Page dissapear"); tokenSource.Cancel(); Debug.WriteLine("Task Cancelled"); }

GetData方法

public async Task GetData() { WebAPI api = new WebAPI(); try { Device.BeginInvokeOnMainThread(() => { PageLoading(); }); string r = await api.GetProfileStatus(token); Device.BeginInvokeOnMainThread(async () => { if (r == "OK") { GetDataSuccess(); } } } catch (Exception e) { // log exception } }

推荐答案

您在错误的位置进行了正确的检查:

You're doing the right check in a wrong place:

var token = tokenSource.Token; task = Task.Run(async () => { while (!token.IsCancellationRequested) { await GetDataAsync(); } }

在这里启动任务,然后在循环中一次又一次地启动它.正确的做法是检查GetData中的令牌,并在可能的情况下进一步访问api变量.在这种情况下,您可以根据需要取消服务呼叫.

Here you start the task, and after that start it again and again in a loop. The right thing to do is check the token inside your GetData, and futher to api variable, if possible. In this case you'll be able to cancel the service call as you need.

旁注:

  • 将事件处理程序设置为async,并且不要将工作包装在Task.Run
  • 设置您的GetData Task<T>,以便您实际上可以将状态返回到调用代码,然后可以删除BeginInvokeOnMainThread,因为await将在异步操作后恢复上下文
  • make your event handlers async, and do not wrap your work in Task.Run
  • make your GetData Task<T> so you can actually return status to the calling code, then you can remove BeginInvokeOnMainThread, as await will restore the context after async operation

因此您的代码将如下所示:

So your code will be something like this:

protected override async void OnAppearing() { base.OnAppearing(); if (task != null && (task.Status == TaskStatus.Running || task.Status == TaskStatus.WaitingToRun || task.Status == TaskStatus.WaitingForActivation)) { Debug.WriteLine("Task has attempted to start while already running"); } else { Debug.WriteLine("Task has began"); var token = tokenSource.Token; PageLoading(); var r = await GetDataAsync(token); if (r == "OK") { GetDataSuccess(); } } } public async Task GetDataAsync(CancellationToken token) { WebAPI api = new WebAPI(); if (token.IsCancellationRequested) { token.ThrowIfCancellationRequested(); } try { return await api.GetProfileStatus(token); } catch (Exception e) { // log exception and return error return "Error"; } }

更多推荐

如何取消任务C#

本文发布于:2023-11-12 21:40:15,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1582597.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!