Updating all view dispatchers to inherit from async dispatcher
This commit is contained in:
Родитель
8e88703683
Коммит
75c5764abf
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче