【发布时间】:2015-11-15 20:26:08
【问题描述】:
我正在使用 MVVM 模式来构建 UWP 应用程序。我已经实现了书中提到的 ICommand 接口:“Microsoft Visual C# 2013 - Step-by-step”。
ICommand 实现:
public class Command : ICommand
{
private Action _methodToExecute;
private Func<bool> _methodCanExecute;
public Command(Action methodToExecute) : this(methodToExecute, null)
{
}
public Command(Action methodToExecute, Func<bool> methodCanExecute)
{
_methodToExecute = methodToExecute;
_methodCanExecute = methodCanExecute;
var dt=new DispatcherTimer();
dt.Tick += (s, e) => CanExecuteChanged?.Invoke(this, EventArgs.Empty);
dt.Interval = new TimeSpan(0, 0, 1);
dt.Start();
}
public bool CanExecute(object parameter) => _methodCanExecute == null ? true : _methodCanExecute();
public void Execute(object parameter) => _methodToExecute();
public event EventHandler CanExecuteChanged;
}
应用程序每运行 3-4 分钟就会崩溃并出现 COM 异常。
System.Runtime.InteropServices.COMException was unhandled by user code
ErrorCode=-2147467259
HResult=-2147467259
Message=Error HRESULT E_FAIL has been returned from a call to a COM component.
Source=mscorlib
StackTrace:
at System.EventHandler`1.Invoke(Object sender, TEventArgs e)
at System.Runtime.InteropServices.WindowsRuntime.ICommandAdapterHelpers.<>c__DisplayClass2.<CreateWrapperHandler>b__3(Object sender, EventArgs e)
at FavQuotesMain.ViewModels.Command.<.ctor>b__3_0(Object s, Object e)
InnerException:
在构建 Win 8.1 应用程序时未发生此异常。 请提出删除此异常的建议。
【问题讨论】:
-
向
CanExecuteChanged事件发送垃圾邮件不是一个好主意。也许有一个替代DispatcherTimer? -
您意识到 DispatcherTimer 在 Command 方法完成后立即被 GC,对吧?无论你在这里做什么,你都做错了。 您想通过使用 DispatcherTimer 来完成什么?将有关此问题的详细信息添加到 edit,我们可以告诉您您应该做什么。
-
@Will Timer 每 1 秒触发一次事件,以查看是否可以执行命令(如上述书中所述)。
-
@MikeEason 是的。我正在考虑使用 Xaml Behavior 将事件直接绑定到使用 CallMethodAction 的方法,而不是使用 Command。
-
不,这是个糟糕的主意。只需在它已更改 时引发 CanExecuteChanged。例如,如果属性 X 依赖于属性 Y 的状态,则在 Y 更改时为 X 触发 CanExecuteChanged。而且,同样,在发布模式应用程序中,您的 DispatcherTimer 几乎永远不会触发,因为在方法退出后它将符合 GC 条件。