Created
March 31, 2016 17:39
-
-
Save wcoder/4bff192c0354bde181a5a97f87613dd1 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class BaseViewModel : BaseNotify | |
{ | |
bool _isBusy = false; | |
CancellationTokenSource _cancellationTokenSource = new CancellationTokenSource(); | |
public bool IsBusy | |
{ | |
get | |
{ | |
return _isBusy; | |
} | |
set | |
{ | |
SetPropertyChanged(ref _isBusy, value); | |
SetPropertyChanged("IsNotBusy"); | |
} | |
} | |
public bool IsNotBusy | |
{ | |
get | |
{ | |
return !IsBusy; | |
} | |
} | |
/// <summary> | |
/// All tasks are created as unstarted tasks and are processe via a proxy method that will run the task safely | |
/// Instead of wrapping every task body in a try/catch, we'll process tasks in RunSafe | |
/// RunSafe will start the task within the scope of a try/catch block and notify the app of any exceptions | |
/// This can also be used to cancel running tasks when a user navigates away from a page - each VM has a cancellation token | |
/// </summary> | |
public async Task RunSafe(Task task, bool notifyOnError = true, [CallerMemberName] string caller = "") | |
{ | |
if(!App.IsNetworkRechable) | |
{ | |
// Please connect to the Information Super Highway | |
return; | |
} | |
Exception exception = null; | |
try | |
{ | |
await Task.Run(() => | |
{ | |
if(!CancellationToken.IsCancellationRequested) | |
{ | |
task.Start(); | |
task.Wait(); | |
} | |
}); | |
} | |
catch(TaskCanceledException) | |
{ | |
Debug.WriteLine("Task Cancelled"); | |
} | |
catch(AggregateException e) | |
{ | |
var ex = e.InnerException; | |
while(ex.InnerException != null) | |
ex = ex.InnerException; | |
exception = ex; | |
} | |
catch(Exception e) | |
{ | |
exception = e; | |
} | |
if(exception != null) | |
{ | |
// log... | |
Debug.WriteLine(exception); | |
if(notifyOnError) | |
{ | |
NotifyException(exception); | |
} | |
} | |
} | |
public void NotifyException(Exception exception) | |
{ | |
// ... | |
} | |
public CancellationToken CancellationToken | |
{ | |
get | |
{ | |
return _cancellationTokenSource.Token; | |
} | |
} | |
public virtual void CancelTasks() | |
{ | |
if(!_cancellationTokenSource.IsCancellationRequested && CancellationToken.CanBeCanceled) | |
{ | |
_cancellationTokenSource.Cancel(); | |
_cancellationTokenSource = new CancellationTokenSource(); | |
} | |
} | |
} | |
/// <summary> | |
/// Helper class that enforces the flag will always get set to false | |
/// </summary> | |
public class Busy : IDisposable | |
{ | |
readonly object _sync = new object(); | |
readonly BaseViewModel _viewModel; | |
public Busy(BaseViewModel viewModel) | |
{ | |
_viewModel = viewModel; | |
Device.BeginInvokeOnMainThread(() => | |
{ | |
lock(_sync) | |
{ | |
_viewModel.IsBusy = true; | |
} | |
}); | |
} | |
public void Dispose() | |
{ | |
Device.BeginInvokeOnMainThread(() => | |
{ | |
lock(_sync) | |
{ | |
_viewModel.IsBusy = false; | |
} | |
}); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment