Windows Phone 8.1 GPS后台任务

Windows Phone 8.1 GPS background task

我正在 WP8.1 上编写一个小的 GPS 跟踪应用程序,但遇到了一些困难。 我可以在任务中创建并用它做任何我需要的事情,但我不能取消它。 作为参考,我使用了这个 answer

这是我使用的任务构造函数(也尝试使用 TaskFactory):

public async void run()
{
    IProgress<object> progress = new Progress<object>(_ => track()); 
    //Above is needed to be able to update the UI component
          Task.Run(async () =>
    //Need to run async because the task is a GPS position call that has a delay
     {
         while (true)
         {
             await Task.Delay(1000);
             progress.Report(null);
         }
     }, tokenSource.Token);
}

我在主 class 部分创建了 tokenSource 对象作为 public 变量,以便能够通过 button_click 停止方法访问它(否则我无法使用tokenSource.Cancel())

当我在构造方法中使用 tokenSource.Cancel() 时一切正常。 但是当我尝试像这样通过 Button_click 使用它时:

private void Button_Stop(object sender, RoutedEventArgs e)
{
    tokenSource.Cancel();
}

没有任何反应。有人有解决办法吗?

这是否意味着如果您每次都使用 async() 创建一个带有新令牌和按钮点击方法的新线程,我是取消线程已经关闭的原始线程?如果有任何想法如何解决这个问题?

.Net 中的取消是合作的。你从外面取消它,你需要从内部观察取消。现在,您只发出取消信号。

您的任务需要以某种方式检查令牌并停止任务:

Task.Run(async () =>
{
    while (true)
    {
        tokenSource.Token.ThrowIfCancellationRequested();
        await Task.Delay(1000);
        progress.Report(null);
    }
}, tokenSource.Token);

因为这正是接受 CancellationTokenTask.Delay 重载的实现方式,您可以只依赖它来抛出异常:

Task.Run(async () =>
{
    while (true)
    {
        await Task.Delay(1000, tokenSource.Token);
        progress.Report(null);
    }
}, tokenSource.Token);