【问题标题】:BeginInvoke not passing data but using Invoke causes exceptionBeginInvoke 不传递数据但使用 Invoke 导致异常
【发布时间】:2011-03-25 13:43:01
【问题描述】:

我有一个在网格视图中显示数据的 Windows 窗体应用程序。数据正在从后台工作线程自动刷新(从数据库中获取)。因此,为了避免任何跨线程引用,在后台线程的 DoWork 方法中,我调用 GridView.BeginInvoke() 并传递消息列表。但是在委托方法中,消息列表是空的。

如果我使用 GridView.invoke(),messageList 确实包含这些值,但有时会出现一个异常,指出“对象当前正在其他地方使用”,我认为这是由于在非UI 线程。

我该如何解决这个问题?

    public delegate void AddMessagesDelegate(List<ClientMessage> tempMessageList);

    private void SearchWorkerDoWork(object sender, DoWorkEventArgs e)
    {
        List<ClientMessage> partList = new List<ClientMessage>();

        View.GridViewtMain.Invoke(new InvokeDelegate(ClearMessagesFromGrid));
        //View.GridViewtMain.BeginInvoke(new InvokeDelegate(ClearMessagesFromGrid));
        partList.AddRange(Model.LoadSearchResult());
        View.GridViewtMain.Invoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        //View.GridViewtMain.BeginInvoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        while (!isCancelled && (partList.Count > 0))
        {
            partList.Clear();
            partList.AddRange(Model.LoadSearchResult());
            View.GridViewtMain.Invoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
            //View.GridViewtMain.BeginInvoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        }
    }

    private void ClearMessagesFromGrid()
    {
        messageDataSource.Clear();
    }

    private void AddMessagesToGrid(List<ClientMessage> tempMessageList)
    {
        View.GridViewMain.BeginDataUpdate();

        foreach (ClientMessage message in tempMessageList)
        {
            messageDataSource.Add(message);
        }
        View.GridViewMain.GridControl.DataSource = messageDataSource;           
        View.GridViewMain.EndDataUpdate();
    }

【问题讨论】:

    标签: c# winforms multithreading invoke begininvoke


    【解决方案1】:
      partList.Clear();
    

    您发布了有效的代码,而不是您有问题的代码。我将假设 BeginInvoke 而不是 Invoke。 partList.Clear() 方法将清空列表,之前委托目标可以使用列表。您应该在 BeginInvoke 调用之后创建列表的新实例。 UI 线程现在可以毫无问题地使用旧列表。大概

        while (!isCancelled)
        {
            partList = new List<ClientMessage>();
            partList.AddRange(Model.LoadSearchResult());
            if (partList.Count == 0) break;
            View.GridViewtMain.BeginInvoke(new AddMessagesDelegate(AddMessagesToGrid), new object[] {partList});
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-04-24
      • 1970-01-01
      • 1970-01-01
      • 2014-08-17
      • 1970-01-01
      • 2018-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多