BeginInvoke不传递数据但使用Invoke导致异常
我有一个 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();
}
I have a windows forms application that shows data in a grid view. The data is being automatically refreshed (fetched from a DB) from a background worker thread. So to avoid any cross thread references, in the DoWork method of the background thread, I call GridView.BeginInvoke() and pass the list of messages. But in the delegate methods, the message list is empty.
If I use GridView.invoke(), the the messageList does contain the values, but sometimes there is an exception which says "object is currently in use elsewhere" which I believe is caused due to referencing UI control on a non-UI thread.
How can I solve this problem?
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();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您发布了有效的代码,而不是您有问题的代码。我假设使用 BeginInvoke 而不是 Invoke。在委托目标可以使用列表之前,partList.Clear() 方法将清空列表。您应该在 BeginInvoke 调用之后创建列表的新实例。 UI 线程现在可以毫无问题地使用旧列表。大致
You posted the code that works instead of the code you have a problem with. I'll assume BeginInvoke instead of Invoke. The partList.Clear() method is going to empty the list, before the delegate target can use the list. You should create a new instance of the list after the BeginInvoke call. The UI thread can now work with the old list without trouble. Roughly