我如何在 .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);
}
我正在使用 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);
}