我如何在 .NET Core 3 class 库中 运行 a Dispatcher.Invoke() ?

How can I run a Dispatcher.Invoke() in a .NET Core 3 class library?

我正在使用 MVVM 开发 WPF/NetCore3.1 应用程序。在视图中有一个绑定到 RelayCommand 的按钮。 ViewModel 与 View 位于不同的 class 库中。在 ViewModel 中启动了一个计时器,它每秒递增一个变量并触发 RelayCommand 的 CanExecuteChanged 事件。

这是我的视图模型:

public ImportExportViewModel()
{
    MakeOfferCommand = new RelayCommand(MakeOffer, CanMakeOffer);


    Timer t = new Timer(1000);
    t.Elapsed += T_Elapsed;
    t.Start();
}

private void T_Elapsed(object sender, ElapsedEventArgs e)
{            
    ElapsedTime++;

    MakeOfferCommand.RaiseCanExecuteChanged();
}

private void MakeOffer()
{
    // TODO Make Offer
}

private bool CanMakeOffer()
{
    return ElapsedTime < 60;
}

这里是 RaiseCanExecuteChanged:

public void RaiseCanExecuteChanged()
{
    var handler = CanExecuteChanged;
    if (handler != null)
    {
        handler(this, new EventArgs());
    }
}

但在这里我得到一个 InvalidOperationException:调用线程无法访问该对象,因为该对象由另一个线程拥有。

通常我会在这里执行一个Dispatcher.Invoke(),但在.NetCore3.1 中似乎不存在。

谁能告诉我如何仍然进行跨线程调用?

您可以使用在每个平台中实现的 IDispatch 接口注入您的视图模型:

接口:

public interface IDispatch
{
    bool CheckAccess();
    void Invoke(Action action);
}

查看模型:

public IDispatch Dispatch { get; set; }

private void T_Elapsed(object sender, ElapsedEventArgs e)
{
    if (Dispatch != null && !Dispatch.CheckAccess())
        Dispatch.Invoke(new Action(() => { /* do something */ }));
    ...
}

WPF 实现:

public class WpfDispatch : IDispatch
{
    private readonly Dispatcher _dispatcher;

    public WpfDispatch(Dispatcher dispatcher) =>
        _dispatcher = dispatcher;

    public bool CheckAccess() => _dispatcher.CheckAccess();

    public void Invoke(Action action) => _dispatcher.Invoke(action);
}