RelayCommand和WeakReference

时间:2012-11-08 01:35:42

标签: mvvm-light

我有以下内容:

public MainViewModel(IDataService dataService)
{
    _dataService = dataService;

    NotWorkingCommand = new RelayCommand(() => 
    dataService.GetData((item, error) =>
    {
        if (error != null)
        {
            // Report error here
            return;
        }
        WelcomeTitle = item.Title;
    }));
}

有人可以解释为什么我的RelayCommand会在一段时间后停止射击吗?我怀疑它与WeakReference中使用的RelayCommand有关,但我没有使用WeakReference的经验。如果我使用_dataService.GetData代替它,它将会起作用。

2 个答案:

答案 0 :(得分:2)

在lambda表达式中,dataService.GetData指令不起作用,因为变量dataService的作用域仅限于构造函数。

相反,您应该将此引用复制到支持字段并改为调用此实例。 当你说使用_dataService.GetData。

时,你认为你已经接近解决方案了
private readonly IDataService _dataService;

public RelayCommand NotWorkingCommand { get; private set; }


public MainViewModel(IDataService dataService)
{
        _dataService = dataService;

        NotWorkingCommand = new RelayCommand(() =>
        _dataService.GetData((item, error) =>
        {
            if (error != null)
            {
                // Report error here
                return;
            }
            WelcomeTitle = item.Title;
        }));
    }

似乎正确创建了委托,因为在创建relay命令时(在ctor的范围内)存在引用,但是在运行时无法调用它,因为它无法正确计算。

答案 1 :(得分:0)

marckm在这里没错,建议使用类级变量也行。但我想澄清一下,这个问题的完整答案应该包含一些关于lambdas中“变量捕获”的信息。

MVVMLight开始使用弱引用之前,方法级变量dataService将通过lambda表达式捕获。通常,一旦方法完成,此变量将超出范围。由于lambda中的变量捕获,这不会发生在这里,这就是为什么lambda的主体将(以后)继续工作的原因。

MVVMLight转移到弱引用之后,代码最初会工作,但是没有类级变量(和赋值),方法级变量最终将被垃圾收集,而RelayCommand将然后停止工作。这正是你在这里看到的(六年前 - 我知道 - 但这个问题今天仍然有效)。