Skip to content

Instantly share code, notes, and snippets.

@gering
Last active May 3, 2017 08:35
Show Gist options
  • Save gering/0aa9750d3c7d14b856d0ed2ba98374a8 to your computer and use it in GitHub Desktop.
Save gering/0aa9750d3c7d14b856d0ed2ba98374a8 to your computer and use it in GitHub Desktop.
Handle execution on main thread in Xamarin projects
using Xamarin.Forms;
namespace System.Threading.Tasks {
public static class MainQueue {
static int mainThreadId = int.MinValue;
public static void Init() {
Init(Environment.CurrentManagedThreadId);
}
public static void Init(int mainThreadId) {
if (MainQueue.mainThreadId != int.MinValue) throw new NotSupportedException("you may call Init() only once");
MainQueue.mainThreadId = mainThreadId;
}
public static bool IsOnMain {
get {
if (mainThreadId == int.MinValue) throw new NotSupportedException("you have to call Init() first");
return Environment.CurrentManagedThreadId == mainThreadId;
}
}
static void EnsureInvokeOnMainThread(Action action) {
if (IsOnMain) {
action();
} else {
Device.BeginInvokeOnMainThread(action);
}
}
public static Task Queue(Action action) {
var tcs = new TaskCompletionSource<object>();
Device.BeginInvokeOnMainThread(() => {
try {
action?.Invoke();
tcs.SetResult(null);
} catch (Exception ex) {
tcs.SetException(ex);
}
});
return tcs.Task;
}
public static Task Run(Action action) {
var tcs = new TaskCompletionSource<object>();
EnsureInvokeOnMainThread(() => {
try {
action?.Invoke();
tcs.SetResult(null);
} catch (Exception ex) {
tcs.SetException(ex);
}
});
return tcs.Task;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment