【问题标题】:The application called an interface that was marshalled for a different thread when using MVVM light messenger应用程序调用了一个接口,该接口在使用 MVVM 轻信使时为不同的线程编组
【发布时间】:2014-11-10 16:17:08
【问题描述】:

我有一个公共计时器,并在它的 Tick 事件中向我的 ViewModel 发送一条消息。我从应用程序中某处的按钮启动计时器。问题是 ViewModel 尝试注册时出现异常(使用 MVVM Light):

“应用程序调用了一个为不同线程编组的接口。(来自 HRESULT 的异常:0x8001010E (RPC_E_WRONG_THREAD))”

这是计时器

public static class SomeManager
{
    private static Timer gAppTimer;
    private static object lockObject = new object();

    public static void StartTimer()
    {
        if (gAppTimer == null)
        {
            lock (lockObject)
            {
                if (gAppTimer == null)
                {
                    gAppTimer = new Timer(OnTimerTick, null, 10000, 10000);
                }
            }
        }
    }

    public static void StopTimer()
    {
        if (gAppTimer != null)
        {
            lock (lockObject)
            {
                if (gAppTimer != null)
                {
                    gAppTimer.Change(Timeout.Infinite, Timeout.Infinite);
                    gAppTimer = null;
                }
            }
        }
    }

    private static void OnTimerTick(object state)
    {
        Action();
    }

    public static void Action()
    {
        GlobalDeclarations.GlobalDataSource.Clear();

        Messenger.Default.Send<ObservableCollection<PersonVMWrapper>>(GlobalDeclarations.GlobalDataSource);
    }
}

这是 ViewModel:

public class PersonVM : INotifyPropertyChanged
{
    ....

    public PersonVM()
    {
        Messenger.Default.Register<ObservableCollection<PersonVMWrapper>>
        (
            this,
            (action) => ReceiveMessage(action)
        );
    }

    private void ReceiveMessage(ObservableCollection<PersonVMWrapper> action)
    {
        foreach (PersonVMWrapper pvmw in action)
        {
            DataSource.Add(pvmw);
        }
    }

    ...

【问题讨论】:

  • 我猜DataSource 是一个 ObservableCollection?如果是这样,您只能为 UI 线程更改它
  • 这是一个 ObservableCollection,是的!那么我应该怎么做才能解决这个问题呢?

标签: c# multithreading asynchronous mvvm windows-phone


【解决方案1】:

如果您的 ObservableCollection 绑定到控件,则只能从 UI 线程添加或删除值。

为此,您可以使用 MVVM Light Toolkit 提供的DispatcherHelper 类:

DispatcherHelper.CheckBeginInvokeOnUI(
    () =>
    {
        foreach (PersonVMWrapper pvmw in action)
        { 
            DataSource.Add(pvmw);
        }
    });

也可以不使用 MVVM Light Toolkit 直接调用调度程序:

Deployment.Current.Dispatcher.BeginInvoke(
    () =>
    {
        foreach (PersonVMWrapper pvmw in action)
        { 
            DataSource.Add(pvmw);
        }
    });

【讨论】:

    猜你喜欢
    • 2017-06-19
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多