This issue is driving me nuts :) Assuming that I have a simple async Task:
async Task AddPoints()
{
await usersDbReference.Child(currentUser).Child("Score").SetValueAsync(newScore).ContinueWith(task =>
{
if(task.IsFaulted || task.IsCanceled)
{
Debug.Log("Couldn't complete task");
}
});
}
What is the simplest way to add the timeout, for example 10 seconds, after which I will show pop up to the user to check his/her internet connection?
Thank you in advance!
EDIT: I tried below code but it makes the unity crash:
int timeout = 1000;
var task = SomeOperationAsync();
if (await Task.WhenAny(task, Task.Delay(timeout)) == task) {
// task completed within timeout
} else {
// timeout logic
}
I'm using Unity (api compatibility level .Net Standard 2.0, I assume that crash is because of this?)
What I want to achieve: In case the user doesn't have the internet connection I want to either timeout the task and cancel it or just cancel it after finding out there is no internet connection.
EDIT:
I modified the code. So I have a simple task with cancel token:
async Task CheckTask(CancellationToken csToken)
{
string firstChild = "user";
string secondChild = "testuser";
await FirebaseDatabase.DefaultInstance.RootReference.Child(firstChild).Child(secondChild).GetValueAsync().ContinueWith(task =>
{
if(task.IsFaulted || task.IsCanceled)
{
Debug.Log("Task was canceled");
}
});
}
Then I'm calling it from async void:
public async void FirebaseLogin()
{
bool taskDidntComplete = false;
Debug.Log("Started task");
CancellationTokenSource cs = new CancellationTokenSource();
try
{
var loginTask = CheckTask(cs.Token);
if(loginTask.IsCanceled)
{
Debug.Log("Canceled");
}
if (await Task.WhenAny(loginTask, Task.Delay(10000)) == loginTask)
{
taskDidntComplete = false;
}
else
{
taskDidntComplete = true;
Debug.Log(taskDidntComplete);
cs.Cancel();
throw new TimeoutException();
}
}
catch (Exception e)
{
Debug.Log(e);
}
finally
{
}
}
And while everything works fine and it shows the exception, it doesn't cancel the task. Would be very grateful if someone could tell me what I'm doing wrong.
EDIT2: Works perfect in Unity, doesnt work on Android... Anyone can help? I'm desperate now haha
public async void FirebaseLogin()
{
Debug.Log("Started task");
CancellationTokenSource cs = new CancellationTokenSource();
try
{
var loginTask = CheckTask(cs.Token);
if(loginTask.IsCanceled)
{
Debug.Log("Canceled");
netTestCheck.text = "Canceled";
}
if (await Task.WhenAny(loginTask, Task.Delay(10000)) == loginTask)
{
//netTestCheck.text = "Completed";
}
else
{
netTestCheck.text = "Failed";
cs.Cancel(false);
//throw new TimeoutException();
}
cs.Token.ThrowIfCancellationRequested();
}
catch (Exception e)
{
netTestCheck.text = "Failed2";
Debug.Log(e);
}
finally
{
}
It unfortunately won't work on Android because app will keep on calling to Firebase. Fortunately found the way around :D