我有一个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();
}
答案 0 :(得分: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});
}