0

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

如果我使用 GridView.invoke(),messageList 确实包含这些值,但有时会出现一个异常,提示“对象当前正在其他地方使用”,我认为这是由于在非 UI 线程上引用 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();
    }
4

1 回答 1

2
  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});
    }
于 2011-03-25T13:51:32.603 回答