ICommand实现会定期抛出COM异常

时间:2015-11-15 20:26:09

标签: c# mvvm uwp icommand

我使用MVVM模式构建UWP应用程序。我已经实现了ICommand接口,如书中所述:" Microsoft Visual C#2013 - 循序渐进"。

ICommand实施:

SELECT softwares.*, count(DISTINCT similar.kid) as shared_tags
FROM softwares
INNER JOIN ( keywords_softwares AS this_software INNER JOIN keywords_softwares AS similar USING (kid) ) ON similar.sid = softwares.id
WHERE this_software.sid=:id
AND   softwares.id != this_software.sid
AND (softwares.subcategory = :subcatid or softwares.category = :catid) 
GROUP BY softwares.id
ORDER BY shared_tags DESC LIMIT 10

每运行3-4分钟,应用程序因COM异常而崩溃。

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;
    }

构建Win 8.1应用程序时未发生此异常。 请提供删除此例外的建议。

3 个答案:

答案 0 :(得分:0)

dt.Tick += (s, e) => CanExecuteChanged?.Invoke(this, EventArgs.Empty);

这很可能是导致您出现问题的原因。我不确定你为什么要向你的CanExecuteChanged发送垃圾邮件,但也许你想重新考虑你的执行模式。

此外,我们不知道您的委托调用的方法。因此可能会有太多原因导致失败。

答案 1 :(得分:0)

我猜你的问题是计时器。

我总是像以下那样实现ICommand:

public class Command : ICommand
{
    private readonly Action<object> execute;
    private readonly Predicate<object> canExecute;

    public Command(Action<object> execute, Predicate<object> canExecute = null)
    {
        if (execute == null)
            throw new ArgumentNullException("execute");
        this.execute = execute;
        this.canExecute = canExecute;
    }

    public void Execute(object parameter)
    {
        execute(parameter);
    }

    public bool CanExecute(object parameter)
    {
        return canExecute == null || canExecute(parameter);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
}

答案 2 :(得分:0)

@Water解决方案是在我们希望View了解Control的更改状态时手动引发CanExecuteChanged

步骤:

  1. 将CanExecuteChanged换行为OnCanExecuteChanged ()
  2. 之类的方法
  3. 将此方法称为相关ViewModel Property Setters。