我需要在依赖服务的状态发生变化时更新ui控制。我有这个示例代码,轮询服务api获取状态并发送结果重新计算并通过主线程更新ui:
public void StartObserving() {
this.cts = new CancellationTokenSource();
this.cts.Token.ThrowIfCancellationRequested();
this.isRunning = true;
var token = this.cts.Token;
Task.Run(async () =>
{
try
{
while (this.isRunning)
{
var result = this.serviceAPI.GetStatus();
this.OnServiceStatusChanged(result);
await Task.Delay(3000);
}
}
catch (OperationCanceledException)
{
this.isRunning = false;
}
catch (Exception ex)
{
this.isRunning = false;
this.logger.LogError(ex);
}
}, token);
}
问题是我想取消上面的任务。当我在这个类的另一个方法中调用this.cts.Cancel()时,我得到了Exception'一个任务被取消了#39;在由EventHandler触发的调度程序上:OnServiceStatusChanged
我应该如何正确实施这种情况?
答案 0 :(得分:0)
我只是检查内部循环中是否取消了令牌,如果是,则退出循环。无需将令牌传递给Task.Run()方法。
public void StartObserving()
{
this.cts = new CancellationTokenSource();
var token = this.cts.Token;
Task.Run(async () =>
{
try
{
while (!token.IsCancellationRequested)
{
var result = this.serviceAPI.GetStatus();
this.OnServiceStatusChanged(result);
await Task.Delay(3000);
}
}
catch
{
}
});
}
答案 1 :(得分:0)
尝试在控制台应用中模拟此行为。任务开始了,但是在调用cts.Cancel()之后,任务继续执行......非常奇怪。
但是,我可以通过简单地将this.isRunning设置为false来取消该任务(而不是调用cts.Cancel())。但我不确定这是否是你想要的解决方案。
答案 2 :(得分:0)
如果dfs = {k:pd.DataFrame(v) for k, v in d.items()}
print (dfs['categories'])
category_id ... vela_defined
0 11decadd ... True
1 c7010763 ... True
[2 rows x 7 columns]
print (dfs['customizable_categories'])
category_id ... updated_at
0 11decadd ... 2017-02-15 01:49:23 -0700
1 fafab667 ... 2017-02-15 01:49:23 -0700
[2 rows x 6 columns]
print (dfs['equipment_category_status_sets'])
Empty DataFrame
Columns: []
Index: []
是一个等待无效的阻止调用,那么您无法正确取消此任务。
正确取消serviceAPI.GetStatus()
方法涉及使用async
标记安全取消点。
您必须将CancellationToken.ThrowIfCancellationRequested()
重写为serviceAPI.GetStatus()
方法async
的结果。它应该包含对可以安全取消的点await
的调用。您可能希望将取消令牌传递给两者该方法,并调用CancellationToken.ThrowIfCancellationRequested()
以获得最佳性能。