尝试跨线程列表框控件时出错

本文关键字:控件 出错 列表 线程 | 更新日期: 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()));