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.
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 when
OnDisappearing()` was called.
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.
The code I have is below:
OnAppearing:
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);
}
}
OnDisappearing:
protected override void OnDisappearing()
{
base.OnDisappearing();
Debug.WriteLine("Page dissapear");
tokenSource.Cancel();
Debug.WriteLine("Task Cancelled");
}
GetData Method
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
}
}