Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
223 views
in Technique[技术] by (71.8m points)

c# - Is there a way I can cause a running method to stop immediately with a cts.Cancel();

I have code that creates a CancellationTokenSource and that passes it to a method.

I have code in another are of the app that issues a cts.Cancel();

Is there a way that I can cause that method to stop immediately without me having to wait for the two lines inside the while loop to finish?

Note that I would be okay if it caused an exception that I could handle.

public async Task OnAppearing()
{
   cts = new CancellationTokenSource();
   await GetCards(cts.Token);
}

public async Task GetCards(CancellationToken ct)
{
   while (!ct.IsCancellationRequested)
   {
      App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts);
      await CheckAvailability();
   }
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

What I can suggest:

  1. Modify GetViewablePhrases and CheckAvailability so you could pass the CancellationToken to them;
  2. Use ct.ThrowIfCancellationRequested() inside these functions;
  3. Try / Catch the OperationCanceledException inside GetCards;

As for your your functions I don't know how exactly they work inside. But let's assume you have a long running iteration inside one of them:

CheckAvailability(CancellationToken ct)
{
    for(;;) 
    {
        // if cts.Cancel() was executed - this method throws the OperationCanceledException
        // if it wasn't the method does nothing
        ct.ThrowIfCancellationRequested(); 
        ...calculations... 
    } 
}

Or let's say you are going to access your database inside one of the function and you know that this process is going to take a while:

CheckAvailability(CancellationToken ct)
{
    ct.ThrowIfCancellationRequested();
    AccessingDatabase();
}

This will not only prevent your functions from proceeding with execution, this also will set the executioner Task status as TaskStatus.Canceled

And don't forget to catch the Exception:

public async Task GetCards(CancellationToken ct)
{
   try
   {
      App.viewablePhrases = App.DB.GetViewablePhrases(Settings.Mode, Settings.Pts, ct);
      await CheckAvailability(ct);
   }
   catch(OperationCanceledException ex)
   {
       // handle the cancelation...
   }
   catch
   {
       // handle the unexpected exception
   }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...