尝试跨线程列表框控件时出错
本文关键字:控件 出错 列表 线程 | 更新日期: 2023-09-27 17:59:29
我正在尝试这样做:
string Proxy = listBox3.SelectedIndex.ToString();
很简单吧?
但在交叉线程中,我得到了这个错误:
跨线程操作无效:控件"listBox3"是从创建它的线程以外的线程访问的。
所以我在谷歌上搜索了一下,发现了这个:
this.Invoke((MethodInvoker)(() => listBox3.Items.Add(Item2add)));
并尝试了一下,认为它会起作用:
string Proxy = listBox3.Invoke((MethodInvoker)(() => listBox3.SelectedIndex.ToString()));
但我得到了这个错误:
附加信息:对象引用未设置为对象的实例。
您可能需要考虑使用一种方法来围绕winforms中的跨线程更新和读取封装(令人惊讶的棘手)逻辑。我在这里创建了一个:扩展Control以提供一致安全的Invoke/BeginInvoke功能是否合适?
它看起来像这样:
/// <summary>
/// Execute a method on the control's owning thread.
/// </summary>
/// <param name="uiElement">The control that is being updated.</param>
/// <param name="updater">The method that updates uiElement.</param>
/// <param name="forceSynchronous">True to force synchronous execution of
/// updater. False to allow asynchronous execution if the call is marshalled
/// from a non-GUI thread. If the method is called on the GUI thread,
/// execution is always synchronous.</param>
public static void SafeInvoke(this Control uiElement, Action updater, bool forceSynchronous)
{
if (uiElement == null)
{
throw new ArgumentNullException("uiElement");
}
if (uiElement.InvokeRequired)
{
if (forceSynchronous)
{
uiElement.Invoke((Action)delegate { SafeInvoke(uiElement, updater, forceSynchronous); });
}
else
{
uiElement.BeginInvoke((Action)delegate { SafeInvoke(uiElement, updater, forceSynchronous); });
}
}
else
{
if (!uiElement.IsHandleCreated)
{
// Do nothing if the handle isn't created already. The user's responsible
// for ensuring that the handle they give us exists.
return;
}
if (uiElement.IsDisposed)
{
throw new ObjectDisposedException("Control is already disposed.");
}
updater();
}
}
首先,那里的代码甚至不应该让你编译。它不允许您从Object隐式转换为String。
我唯一能看到这会产生这个错误的方法是,如果你调用它的线程上不存在listBox3。确保您是从UI线程调用它(假设这是您的listBox所在的位置)。
试试这个代码,看看它是否有帮助:
string Proxy;
listBox3.Invoke((MethodInvoker)(() => Proxy = listBox3.SelectedIndex.ToString()));