Updating all view dispatchers to inherit from async dispatcher

This commit is contained in:
Nick Randolph 2018-04-03 16:40:26 +10:00
Родитель 8e88703683
Коммит 75c5764abf
17 изменённых файлов: 95 добавлений и 34 удалений

Просмотреть файл

@ -0,0 +1,18 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading.Tasks;
namespace MvvmCross.Base
{
// Note: The long term goal should be to deprecate IMvxMainThreadDispatcher
// As such, even though the implementation of this interface also implements
// IMvxMainThreadDispatcher, this interface should not inherit from IMvxMainThreadDispatcher
public interface IMvxMainThreadAsyncDispatcher
{
Task ExecuteOnMainThreadAsync(Action action, bool maskExceptions = true);
Task ExecuteOnMainThreadAsync(Func<Task> action, bool maskExceptions = true);
}
}

Просмотреть файл

@ -9,12 +9,7 @@ namespace MvvmCross.Base
{
public interface IMvxMainThreadDispatcher
{
[Obsolete("Use IMvxMainThreadAsyncDispatcher.ExecuteOnMainThreadAsync instead")]
bool RequestMainThreadAction(Action action, bool maskExceptions = true);
}
public interface IMvxMainThreadAsyncDispatcher
{
Task<bool> ExecuteOnMainThreadAsync(Action action, bool maskExceptions = true);
Task<bool> ExecuteOnMainThreadAsync(Func<Task> action, bool maskExceptions = true);
}
}

Просмотреть файл

@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.
using System;
using System.Threading.Tasks;
namespace MvvmCross.Base
{
public abstract class MvxMainThreadAsyncDispatcher : MvxMainThreadDispatcher, IMvxMainThreadAsyncDispatcher
{
public Task ExecuteOnMainThreadAsync(Action action, bool maskExceptions = true)
{
var asyncAction = new Func<Task>(() =>
{
action();
return Task.CompletedTask;
});
return ExecuteOnMainThreadAsync(asyncAction, maskExceptions);
}
public async Task ExecuteOnMainThreadAsync(Func<Task> action, bool maskExceptions = true)
{
var completion = new TaskCompletionSource<bool>();
var syncAction = new Action(async () =>
{
await action();
completion.SetResult(true);
});
RequestMainThreadAction(syncAction, maskExceptions);
// If we're already on main thread, then the action will
// have already completed at this point, so can just return
if (completion.Task.IsCompleted)
return;
// Make sure we don't introduce weird locking issues
// blocking on the completion source by jumping onto
// a new thread to wait
await Task.Run(async () => await completion.Task);
}
}
}

Просмотреть файл

@ -4,12 +4,13 @@
using System;
using System.Reflection;
using System.Threading.Tasks;
using MvvmCross.Exceptions;
using MvvmCross.Logging;
namespace MvvmCross.Base
{
public abstract class MvxMainThreadDispatcher : MvxSingleton<IMvxMainThreadDispatcher>
public abstract class MvxMainThreadDispatcher : MvxSingleton<IMvxMainThreadDispatcher>, IMvxMainThreadDispatcher
{
protected static void ExceptionMaskedAction(Action action, bool maskExceptions)
{
@ -34,5 +35,7 @@ namespace MvvmCross.Base
throw exception;
}
}
public abstract bool RequestMainThreadAction(Action action, bool maskExceptions = true);
}
}

Просмотреть файл

@ -339,6 +339,7 @@ namespace MvvmCross.Core
{
var dispatcher = CreateViewDispatcher();
Mvx.RegisterSingleton(dispatcher);
Mvx.RegisterSingleton<IMvxMainThreadAsyncDispatcher>(dispatcher);
Mvx.RegisterSingleton<IMvxMainThreadDispatcher>(dispatcher);
}

Просмотреть файл

@ -10,9 +10,9 @@ using MvvmCross.Base;
namespace MvvmCross.Platforms.Android.Views
{
public class MvxAndroidMainThreadDispatcher : MvxMainThreadDispatcher
public class MvxAndroidMainThreadDispatcher : MvxMainThreadAsyncDispatcher
{
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
if (Application.SynchronizationContext == SynchronizationContext.Current)
action();

Просмотреть файл

@ -1,4 +1,4 @@
// Licensed to the .NET Foundation under one or more agreements.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MS-PL license.
// See the LICENSE file in the project root for more information.
@ -10,10 +10,10 @@ using MvvmCross.Views;
namespace MvvmCross.Platforms.Console.Views
{
public class MvxConsoleViewDispatcher
: MvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
, IMvxViewDispatcher
{
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
action();
return true;

Просмотреть файл

@ -11,7 +11,7 @@ using UIKit;
namespace MvvmCross.Platforms.Ios.Views
{
public abstract class MvxIosUIThreadDispatcher
: MvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
private readonly SynchronizationContext _uiSynchronizationContext;
@ -22,7 +22,7 @@ namespace MvvmCross.Platforms.Ios.Views
throw new MvxException("SynchronizationContext must not be null - check to make sure Dispatcher is created on UI thread");
}
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
if (_uiSynchronizationContext == SynchronizationContext.Current)
action();

Просмотреть файл

@ -12,7 +12,7 @@ using MvvmCross.Exceptions;
namespace MvvmCross.Platforms.Mac.Views
{
public abstract class MvxMacUIThreadDispatcher
: MvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
private readonly SynchronizationContext _uiSynchronizationContext;
@ -23,7 +23,7 @@ namespace MvvmCross.Platforms.Mac.Views
throw new MvxException("SynchronizationContext must not be null - check to make sure Dispatcher is created on UI thread");
}
public bool RequestMainThreadAction(Action action,
public override bool RequestMainThreadAction(Action action,
bool maskExceptions = true)
{
if (_uiSynchronizationContext == SynchronizationContext.Current)

Просмотреть файл

@ -11,7 +11,7 @@ using UIKit;
namespace MvvmCross.Platforms.Tvos.Views
{
public abstract class MvxTvosUIThreadDispatcher
: MvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
private readonly SynchronizationContext _uiSynchronizationContext;
@ -22,7 +22,7 @@ namespace MvvmCross.Platforms.Tvos.Views
throw new MvxException("SynchronizationContext must not be null - check to make sure Dispatcher is created on UI thread");
}
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
if (_uiSynchronizationContext == SynchronizationContext.Current)
action();

Просмотреть файл

@ -8,7 +8,7 @@ using MvvmCross.Base;
namespace MvvmCross.Platforms.Uap.Views
{
public class MvxWindowsMainThreadDispatcher : MvxMainThreadDispatcher
public class MvxWindowsMainThreadDispatcher : MvxMainThreadAsyncDispatcher
{
private readonly CoreDispatcher _uiDispatcher;
@ -17,7 +17,7 @@ namespace MvvmCross.Platforms.Uap.Views
_uiDispatcher = uiDispatcher;
}
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
if (_uiDispatcher.HasThreadAccess)
{

Просмотреть файл

@ -9,7 +9,7 @@ using MvvmCross.Base;
namespace MvvmCross.Platforms.Wpf.Views
{
public class MvxWpfUIThreadDispatcher
: MvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
private readonly Dispatcher _dispatcher;
@ -18,7 +18,7 @@ namespace MvvmCross.Platforms.Wpf.Views
_dispatcher = dispatcher;
}
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
if (_dispatcher.CheckAccess())
{

Просмотреть файл

@ -7,7 +7,7 @@ using MvvmCross.ViewModels;
namespace MvvmCross.Views
{
public interface IMvxViewDispatcher : IMvxMainThreadDispatcher
public interface IMvxViewDispatcher : IMvxMainThreadDispatcher, IMvxMainThreadAsyncDispatcher
{
bool ShowViewModel(MvxViewModelRequest request);

Просмотреть файл

@ -8,7 +8,7 @@ using MvvmCross.Base;
namespace MvvmCross.UnitTest.Mocks.Dispatchers
{
public class CallbackMockMainThreadDispatcher
: MvxMainThreadDispatcher, IMvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
private readonly Func<Action, bool> _callback;
@ -17,7 +17,7 @@ namespace MvvmCross.UnitTest.Mocks.Dispatchers
_callback = callback;
}
public virtual bool RequestMainThreadAction(Action action,
public override bool RequestMainThreadAction(Action action,
bool maskExceptions = true)
{
return _callback(action);

Просмотреть файл

@ -8,11 +8,11 @@ using MvvmCross.Base;
namespace MvvmCross.UnitTest.Mocks.Dispatchers
{
public class CountingMockMainThreadDispatcher
: MvxMainThreadDispatcher, IMvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
public int Count { get; set; }
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
{
Count++;
return true;

Просмотреть файл

@ -8,9 +8,9 @@ using MvvmCross.Base;
namespace MvvmCross.UnitTest.Mocks.Dispatchers
{
public class InlineMockMainThreadDispatcher
: MvxMainThreadDispatcher, IMvxMainThreadDispatcher
: MvxMainThreadAsyncDispatcher
{
public virtual bool RequestMainThreadAction(Action action,
public override bool RequestMainThreadAction(Action action,
bool maskExceptions = true)
{
action();

Просмотреть файл

@ -5,6 +5,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using MvvmCross.Base;
using MvvmCross.Logging;
using MvvmCross.Tests;
@ -26,7 +27,7 @@ namespace MvvmCross.UnitTest.Mocks.Dispatchers
return true;
}
public virtual bool ShowViewModel(MvxViewModelRequest request)
public virtual Task<bool> ShowViewModel(MvxViewModelRequest request)
{
var debugString = $"ShowViewModel: '{request.ViewModelType.Name}' ";
if (request.ParameterValues != null)
@ -36,13 +37,13 @@ namespace MvvmCross.UnitTest.Mocks.Dispatchers
MvxTestLog.Instance.Log(MvxLogLevel.Debug, () => debugString);
Requests.Add(request);
return true;
return Task.FromResult(true);
}
public virtual bool ChangePresentation(MvxPresentationHint hint)
public virtual Task<bool> ChangePresentation(MvxPresentationHint hint)
{
Hints.Add(hint);
return true;
return Task.FromResult(true);
}
}