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
You're doing the right check in a wrong place:
var token = tokenSource.Token;
task = Task.Run(async () =>
{
while (!token.IsCancellationRequested)
{
await GetDataAsync();
}
}
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.
Side notes:
async
, and do not wrap your work in Task.Run
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 operationSo 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";
}
}