【问题标题】:C# - Program FreezeC# - 程序冻结
【发布时间】:2018-03-25 10:17:17
【问题描述】:

我制作了代理检查器,由于某种原因,当我单击“检查”按钮时,程序只是冻结,直到工作完成。

我尝试将代码移至Backgroundworker:

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        WebProxy myproxy;
        foreach (string proxy in Proxies)
        {
            try
            {
                myproxy = new WebProxy(proxy);
                WebRequest request = WebRequest.Create("https://www.google.co.il/");
                request.Timeout = TimeOut;
                request.Proxy = myproxy;
                WebResponse re = request.GetResponse();
                richTextBox1.AppendText(proxy + "\r\n");
                Good++;
                label3.Text = "Good: " + Good.ToString();
            }
            catch (Exception)
            {
                Bad++;
                label4.Text = "Bad: " + Bad.ToString();
            }
        }
        MessageBox.Show("Done");
    }

但由于某种原因,我收到此错误:

System.InvalidOperationException: '跨线程操作无效: 控件'richTextBox1'从一个线程而不是它的线程访问 创建于。'

所以我尝试删除 label3.Text 和 label4.Text。 但是当我点击“检查”按钮时,我发现什么都没有发生。

所以我尝试添加 MessageBox.Show("some text") 以查看它是否正常工作,我看到了消息框,但看起来线程跳过了检查。

我能做什么?

“检查”按钮代码:

 label1.Text = "Lines: 0";
        richTextBox1.Clear();
        backgroundWorker1.RunWorkerAsync();

完整代码:

 public partial class Form1 : Form
{
    WebClient X = new WebClient();
    string url = "";
    ArrayList Proxies = new ArrayList();
    int TimeOut = 3000, Good = 0, Bad = 0;

    public Form1()
    {
        InitializeComponent();
    }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            if (radioHTTP.Checked)
            {
                byte[] proxies = X.DownloadData(new Uri("https://www.free-proxy-list.net/"));
                MatchCollection M = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}</td><td>\\d{1,6}");
                foreach (Match m in M)
                    richTextBox1.AppendText(m.Value.Replace("</td><td>", ":") + "\r\n");
            }
            if (radioSocks.Checked)
            {
                byte[] proxies = X.DownloadData(new Uri("https://www.socks-proxy.net/"));
                MatchCollection M = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}</td><td>\\d{1,6}");
                foreach (Match m in M)
                    richTextBox1.AppendText(m.Value.Replace("</td><td>", ":") + "\r\n");
            }
            if (radioSSL.Checked)
            {
                byte[] proxies = X.DownloadData(new Uri("https://www.sslproxies.org/"));
                MatchCollection M = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}</td><td>\\d{1,6}");
                foreach (Match m in M)
                    richTextBox1.AppendText(m.Value.Replace("</td><td>", ":") + "\r\n");
            }
            if (radioCustom.Checked)
            {
                byte[] proxies = X.DownloadData(new Uri(url));
                MatchCollection A = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}</td><td>\\d{1,6}");
                MatchCollection B = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}\\d{1,6}");
                MatchCollection C = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}\",\"port\":\"\\d{2,6}");
                MatchCollection D = Regex.Matches(Encoding.UTF8.GetString(proxies, 0, proxies.Length), "\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}</td><td class=\"column-2\">\\d{2,6}");
                foreach (Match m in A)
                    richTextBox1.AppendText(m.Value.Replace("</td><td>", ":") + "\r\n");
                foreach (Match m in B)
                    richTextBox1.AppendText(m.Value + "\r\n");
                foreach (Match m in C)
                    richTextBox2.AppendText(m.Value.Replace("\",\"port\":\"", ":") + "\r\n");
                foreach (Match m in D)
                    richTextBox2.AppendText(m.Value.Replace("</td><td class=\"column-2\">", ":") + "\r\n");
            }
            string[] lines = richTextBox1.Lines;
            foreach (string line in lines)
                Proxies.Add(line);
            label1.Text = "Lines: " + Proxies.Count;
        }catch
        {

        }

    }
    private void button4_Click(object sender, EventArgs e)
    {
        label1.Text = "Lines: 0";
        richTextBox1.Clear();
        backgroundWorker1.RunWorkerAsync();
    }
    private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
    {
        // backgroundWorker1.ReportProgress(0, "Working...");
        WebProxy myproxy;
        foreach (string proxy in Proxies)
        {
            try
            {
                myproxy = new WebProxy(proxy);
                WebRequest request = WebRequest.Create("https://www.google.co.il/");
                request.Timeout = TimeOut;
                request.Proxy = myproxy;
                WebResponse re = request.GetResponse();
                richTextBox1.AppendText(proxy + "\r\n");
                Good++;
                this.Invoke((Action)delegate {
                    label3.Text = "Good: " + Good.ToString();
                });
            }
            catch (Exception)
            {
                Bad++;
                this.Invoke((Action)delegate {
                    label4.Text = "Bad: " + Good.ToString();
                });
            }
        }
        //backgroundWorker1.ReportProgress(100, "Done");
    }

非常感谢

【问题讨论】:

  • 您似乎正在尝试从另一个线程访问 UI 元素。
  • 我试图让它在单独的线程上运行,但我一直失败。我试过 Thread thread = new Thread(method); thread.Start(): 我也遇到了同样的问题

标签: c# multithreading


【解决方案1】:

WinForms 控件不能在创建它们的线程之外进行修改。

所以做这样的事情:

label3.Text = "Good: " + Good.ToString();

将在后台工作人员中失败,因为后台工作人员任务在单独的线程中运行。

要解决这个问题,您可以像这样在表单线程上调用委托:

this.Invoke((Action) delegate {
    label3.Text = "Good: " + Good.ToString();
});

使用invoke 函数将强制代码与表单的 UI 在同一线程上运行。

【讨论】:

  • BackgroundWorker 类有一个ProgressChanged 事件是有原因的。
  • 这实际上是我忘记ProgressChanged的一个好点,我的答案现在我想起来更像是一种幼稚的方法。
  • 但是当我点击“检查”按钮时,什么也没有发生
  • 您必须向我们提供更多代码和更好的问题定义才能诊断问题。
  • 我编辑了问题,所以现在你可以看到所有的代码
猜你喜欢
  • 2021-12-04
  • 2018-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-12-15
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多