【问题标题】:TargetParameterCountException: the parameter count mismatchTargetParameterCountException:参数计数不匹配
【发布时间】:2017-12-31 02:01:52
【问题描述】:

在我的 WPF MVVM 应用程序的视图模型和数据模型下方。我在执行调用时遇到问题(见下文),抛出异常参数计数不匹配。 “getDataFromDatabase”方法返回“UserData”的集合。那么如何解决呢?

查看模型:

public class MyViewModel : BaseViewModel
{
    private static Dispatcher _dispatcher;
    public ObservableCollection<UserData> lstUsers

    public ObservableCollection<UserData> LstUsers
    {
        get
        {
            return this.lstUsers;
        }

        private set
        {
            this.lstUsers= value;
            OnPropertyChanged("LstUsers");
        }
    }

    // LoadData is called from the constructor of the view code-behind (xaml.cs) once DataContext is correctly set.
    public void LoadData()
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback((o) =>
        {
            var result = getDataFromDatabase();
            UIThread((p) => LstUsers = result);
        }));
    }

    ObservableCollection<UserData> getDataFromDatabase()
    {            
        return this.RequestDataToDatabase();
    }

    static void UIThread(Action<object> a)
    {
        if(_dispatcher == null) 
        {
           _dispatcher = Dispatcher.CurrentDispatcher;
        }

        _dispatcher.Invoke(a); <---- HERE EXCEPTION IS THROWN
    }
}

数据模型:

public class UserData
{
   public string ID{ get; set; }
   public string Name { get; set; }
   public string Surname { get; set; }

   // Other properties
}

【问题讨论】:

  • 你试过调试吗?你的方法getDataFromDatabase 会被调用吗?您应该在构造函数中设置调度程序,而不是在方法UIThread。
  • @MightyBadaboom 是的,方法 getDataFromDatabase 被调用并正确返回集合。请参阅我更新的帖子。 ThreadPool 是在视图模型中的一个方法上创建的,一旦正确设置了数据上下文,该方法就会从视图(构造函数)中调用。
  • 您介意再次调试吗,这次更详细,逐行调试会话,以便您可以找到引发错误的确切代码行?

标签: c# wpf mvvm .net-3.5 dispatcher


【解决方案1】:

Action&lt;object&gt; 是一个带有 object 类型参数的 Action。它必须通过带有单个参数的Invoke(Delegate method, params object[] args) 重载来调用:

Application.Current.Dispatcher.Invoke(a, someObject);

所以把Action&lt;object&gt;改成Action:

static void UIThread(Action a)
{
    Application.Current.Dispatcher.Invoke(a);
}

然后这样称呼它:

UIThread(() => LstUsers = result);

您可能还想让您的 LoadData 方法异步并像这样编写它:

public async Task LoadData()
{
    await Task.Run(() =>
    {
        var result = getDataFromDatabase();
        Application.Current.Dispatcher.Invoke(() => LstUsers = result);
    });
}

【讨论】:

  • 工作!我也非常喜欢您使 LoadData 方法异步的解决方案。不幸的是,NET 3.5 不支持任务,所以可以以某种方式对其进行调整吗?
  • 也许你可以使用Task Parallel Library for .NET 3.5 和Microsoft Async。否则,ThreadPool.QueueUserWorkItem 应该没问题。
猜你喜欢
  • 2011-11-17
  • 1970-01-01
  • 1970-01-01
  • 2011-02-10
  • 1970-01-01
  • 2012-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多