You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#应用运行时如何解决System.InvalidOperationException异常?

错误原因及解决方案

错误根源

WinForms控件属于单线程组件,所有控件的创建、读取、修改操作都必须在创建它们的UI线程中执行。你用Task启动的后台线程(线程池线程)直接访问richTextBox7.Text、修改richTextBox6.Text等控件属性,违反了线程安全规则,因此抛出System.InvalidOperationException。

解决方案

方案1:用Control.Invoke切换到UI线程操作控件

修改FindVariation方法,所有涉及控件的读写操作都通过Invoke切换回UI线程:

private void FindVariation()
{
    string[] idlist;
    // 读取richTextBox7内容,切换到UI线程执行
    richTextBox7.Invoke(new Action(() => {
        idlist = richTextBox7.Text.Split('\n');
    }));

    for (int i = 0; i < idlist.Length; i++)
    {
        string id = idlist[i].Trim();
        if(string.IsNullOrEmpty(id)) continue;
        
        string url = "http://www.ebay.com/itm/" + id;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        using(HttpWebResponse response = (HttpWebResponse)request.GetResponse())
        using(StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            string a = sr.ReadToEnd();
            string source = string.Join(Environment.NewLine,
                a.Split(',', ']', '[')
                .Where(m => m.Length == 12 && m.All(char.IsDigit)));

            if (!string.IsNullOrEmpty(source))
            {
                // 修改richTextBox6,切换到UI线程
                richTextBox6.Invoke(new Action(() => {
                    richTextBox6.Text += id + Environment.NewLine;
                }));
            }
            // 修改richTextBox1,切换到UI线程
            richTextBox1.Invoke(new Action(() => {
                richTextBox1.Text = richTextBox7.Text;
            }));
        }
    }
}

方案2:用async/await实现优雅的异步操作(推荐)

这种方式无需手动管理线程,await会自动在异步操作完成后切回UI线程,代码更简洁:

private async Task FindVariationAsync()
{
    // 这里处于UI线程,可直接读取控件
    string[] idlist = richTextBox7.Text.Split('\n');
    for (int i = 0; i < idlist.Length; i++)
    {
        string id = idlist[i].Trim();
        if(string.IsNullOrEmpty(id)) continue;
        
        string url = "http://www.ebay.com/itm/" + id;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
        // 使用异步方法GetResponseAsync,不阻塞UI线程
        using(HttpWebResponse response = (HttpWebResponse)await request.GetResponseAsync())
        using(StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            string a = await sr.ReadToEndAsync();
            string source = string.Join(Environment.NewLine,
                a.Split(',', ']', '[')
                .Where(m => m.Length == 12 && m.All(char.IsDigit)));

            if (!string.IsNullOrEmpty(source))
            {
                // await后自动回到UI线程,可直接修改控件
                richTextBox6.Text += id + Environment.NewLine;
            }
            richTextBox1.Text = richTextBox7.Text;
        }
    }
}

调用方式(比如在按钮点击事件中):

private async void btnStart_Click(object sender, EventArgs e)
{
    await FindVariationAsync();
}

注意事项

  • 所有WinForms控件的操作必须在UI线程执行,后台线程绝对不能直接读写控件属性
  • 用using语句管理HttpWebResponse和StreamReader,确保网络资源及时释放
  • async/await是.NET异步编程的标准模式,比手动创建Task+Invoke更易维护

内容的提问来源于stack exchange,提问作者Ryan Gabriel

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.24 18:37:13