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
|
public interface IMvxMainThreadDispatcher
|
||||||
{
|
{
|
||||||
|
[Obsolete("Use IMvxMainThreadAsyncDispatcher.ExecuteOnMainThreadAsync instead")]
|
||||||
bool RequestMainThreadAction(Action action, bool maskExceptions = true);
|
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;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using MvvmCross.Exceptions;
|
using MvvmCross.Exceptions;
|
||||||
using MvvmCross.Logging;
|
using MvvmCross.Logging;
|
||||||
|
|
||||||
namespace MvvmCross.Base
|
namespace MvvmCross.Base
|
||||||
{
|
{
|
||||||
public abstract class MvxMainThreadDispatcher : MvxSingleton<IMvxMainThreadDispatcher>
|
public abstract class MvxMainThreadDispatcher : MvxSingleton<IMvxMainThreadDispatcher>, IMvxMainThreadDispatcher
|
||||||
{
|
{
|
||||||
protected static void ExceptionMaskedAction(Action action, bool maskExceptions)
|
protected static void ExceptionMaskedAction(Action action, bool maskExceptions)
|
||||||
{
|
{
|
||||||
|
@ -34,5 +35,7 @@ namespace MvvmCross.Base
|
||||||
throw exception;
|
throw exception;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract bool RequestMainThreadAction(Action action, bool maskExceptions = true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,6 +339,7 @@ namespace MvvmCross.Core
|
||||||
{
|
{
|
||||||
var dispatcher = CreateViewDispatcher();
|
var dispatcher = CreateViewDispatcher();
|
||||||
Mvx.RegisterSingleton(dispatcher);
|
Mvx.RegisterSingleton(dispatcher);
|
||||||
|
Mvx.RegisterSingleton<IMvxMainThreadAsyncDispatcher>(dispatcher);
|
||||||
Mvx.RegisterSingleton<IMvxMainThreadDispatcher>(dispatcher);
|
Mvx.RegisterSingleton<IMvxMainThreadDispatcher>(dispatcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,9 +10,9 @@ using MvvmCross.Base;
|
||||||
|
|
||||||
namespace MvvmCross.Platforms.Android.Views
|
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)
|
if (Application.SynchronizationContext == SynchronizationContext.Current)
|
||||||
action();
|
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.
|
// The .NET Foundation licenses this file to you under the MS-PL license.
|
||||||
// See the LICENSE file in the project root for more information.
|
// See the LICENSE file in the project root for more information.
|
||||||
|
|
||||||
|
@ -10,10 +10,10 @@ using MvvmCross.Views;
|
||||||
namespace MvvmCross.Platforms.Console.Views
|
namespace MvvmCross.Platforms.Console.Views
|
||||||
{
|
{
|
||||||
public class MvxConsoleViewDispatcher
|
public class MvxConsoleViewDispatcher
|
||||||
: MvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
, IMvxViewDispatcher
|
, IMvxViewDispatcher
|
||||||
{
|
{
|
||||||
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
action();
|
action();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -11,7 +11,7 @@ using UIKit;
|
||||||
namespace MvvmCross.Platforms.Ios.Views
|
namespace MvvmCross.Platforms.Ios.Views
|
||||||
{
|
{
|
||||||
public abstract class MvxIosUIThreadDispatcher
|
public abstract class MvxIosUIThreadDispatcher
|
||||||
: MvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
private readonly SynchronizationContext _uiSynchronizationContext;
|
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");
|
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)
|
if (_uiSynchronizationContext == SynchronizationContext.Current)
|
||||||
action();
|
action();
|
||||||
|
|
|
@ -12,7 +12,7 @@ using MvvmCross.Exceptions;
|
||||||
namespace MvvmCross.Platforms.Mac.Views
|
namespace MvvmCross.Platforms.Mac.Views
|
||||||
{
|
{
|
||||||
public abstract class MvxMacUIThreadDispatcher
|
public abstract class MvxMacUIThreadDispatcher
|
||||||
: MvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
private readonly SynchronizationContext _uiSynchronizationContext;
|
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");
|
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)
|
bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
if (_uiSynchronizationContext == SynchronizationContext.Current)
|
if (_uiSynchronizationContext == SynchronizationContext.Current)
|
||||||
|
|
|
@ -11,7 +11,7 @@ using UIKit;
|
||||||
namespace MvvmCross.Platforms.Tvos.Views
|
namespace MvvmCross.Platforms.Tvos.Views
|
||||||
{
|
{
|
||||||
public abstract class MvxTvosUIThreadDispatcher
|
public abstract class MvxTvosUIThreadDispatcher
|
||||||
: MvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
private readonly SynchronizationContext _uiSynchronizationContext;
|
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");
|
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)
|
if (_uiSynchronizationContext == SynchronizationContext.Current)
|
||||||
action();
|
action();
|
||||||
|
|
|
@ -8,7 +8,7 @@ using MvvmCross.Base;
|
||||||
|
|
||||||
namespace MvvmCross.Platforms.Uap.Views
|
namespace MvvmCross.Platforms.Uap.Views
|
||||||
{
|
{
|
||||||
public class MvxWindowsMainThreadDispatcher : MvxMainThreadDispatcher
|
public class MvxWindowsMainThreadDispatcher : MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
private readonly CoreDispatcher _uiDispatcher;
|
private readonly CoreDispatcher _uiDispatcher;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ namespace MvvmCross.Platforms.Uap.Views
|
||||||
_uiDispatcher = uiDispatcher;
|
_uiDispatcher = uiDispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
if (_uiDispatcher.HasThreadAccess)
|
if (_uiDispatcher.HasThreadAccess)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@ using MvvmCross.Base;
|
||||||
namespace MvvmCross.Platforms.Wpf.Views
|
namespace MvvmCross.Platforms.Wpf.Views
|
||||||
{
|
{
|
||||||
public class MvxWpfUIThreadDispatcher
|
public class MvxWpfUIThreadDispatcher
|
||||||
: MvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
private readonly Dispatcher _dispatcher;
|
private readonly Dispatcher _dispatcher;
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace MvvmCross.Platforms.Wpf.Views
|
||||||
_dispatcher = dispatcher;
|
_dispatcher = dispatcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
if (_dispatcher.CheckAccess())
|
if (_dispatcher.CheckAccess())
|
||||||
{
|
{
|
||||||
|
|
|
@ -7,10 +7,10 @@ using MvvmCross.ViewModels;
|
||||||
|
|
||||||
namespace MvvmCross.Views
|
namespace MvvmCross.Views
|
||||||
{
|
{
|
||||||
public interface IMvxViewDispatcher : IMvxMainThreadDispatcher
|
public interface IMvxViewDispatcher : IMvxMainThreadDispatcher, IMvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
bool ShowViewModel(MvxViewModelRequest request);
|
bool ShowViewModel(MvxViewModelRequest request);
|
||||||
|
|
||||||
bool ChangePresentation(MvxPresentationHint hint);
|
bool ChangePresentation(MvxPresentationHint hint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ using MvvmCross.Base;
|
||||||
namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
||||||
{
|
{
|
||||||
public class CallbackMockMainThreadDispatcher
|
public class CallbackMockMainThreadDispatcher
|
||||||
: MvxMainThreadDispatcher, IMvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
private readonly Func<Action, bool> _callback;
|
private readonly Func<Action, bool> _callback;
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool RequestMainThreadAction(Action action,
|
public override bool RequestMainThreadAction(Action action,
|
||||||
bool maskExceptions = true)
|
bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
return _callback(action);
|
return _callback(action);
|
||||||
|
|
|
@ -8,11 +8,11 @@ using MvvmCross.Base;
|
||||||
namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
||||||
{
|
{
|
||||||
public class CountingMockMainThreadDispatcher
|
public class CountingMockMainThreadDispatcher
|
||||||
: MvxMainThreadDispatcher, IMvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
public int Count { get; set; }
|
public int Count { get; set; }
|
||||||
|
|
||||||
public bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
public override bool RequestMainThreadAction(Action action, bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
Count++;
|
Count++;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -8,9 +8,9 @@ using MvvmCross.Base;
|
||||||
namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
||||||
{
|
{
|
||||||
public class InlineMockMainThreadDispatcher
|
public class InlineMockMainThreadDispatcher
|
||||||
: MvxMainThreadDispatcher, IMvxMainThreadDispatcher
|
: MvxMainThreadAsyncDispatcher
|
||||||
{
|
{
|
||||||
public virtual bool RequestMainThreadAction(Action action,
|
public override bool RequestMainThreadAction(Action action,
|
||||||
bool maskExceptions = true)
|
bool maskExceptions = true)
|
||||||
{
|
{
|
||||||
action();
|
action();
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
using MvvmCross.Base;
|
using MvvmCross.Base;
|
||||||
using MvvmCross.Logging;
|
using MvvmCross.Logging;
|
||||||
using MvvmCross.Tests;
|
using MvvmCross.Tests;
|
||||||
|
@ -26,7 +27,7 @@ namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool ShowViewModel(MvxViewModelRequest request)
|
public virtual Task<bool> ShowViewModel(MvxViewModelRequest request)
|
||||||
{
|
{
|
||||||
var debugString = $"ShowViewModel: '{request.ViewModelType.Name}' ";
|
var debugString = $"ShowViewModel: '{request.ViewModelType.Name}' ";
|
||||||
if (request.ParameterValues != null)
|
if (request.ParameterValues != null)
|
||||||
|
@ -36,13 +37,13 @@ namespace MvvmCross.UnitTest.Mocks.Dispatchers
|
||||||
MvxTestLog.Instance.Log(MvxLogLevel.Debug, () => debugString);
|
MvxTestLog.Instance.Log(MvxLogLevel.Debug, () => debugString);
|
||||||
|
|
||||||
Requests.Add(request);
|
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);
|
Hints.Add(hint);
|
||||||
return true;
|
return Task.FromResult(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче