【问题标题】:C# - Run Task in foreach listviewitem with xNet RequestC# - 使用 xNet 请求在 foreach listviewitem 中运行任务
【发布时间】:2020-05-06 05:35:10
【问题描述】:

我的代码:

foreach (ListViewItem item in list.Items)
        {
            string url, path, host;
            url = item.SubItems[0].Text; // example "www.google.com/"
            path =  item.SubItems[1].Text; // example = "login/"
            host = (item.SubItems[2].Text); // example = "123.123.123:232";
            bool ping = Request(url, path, host);
            if (ping) {
            item.Subitems[3].Text = "This is good";
            } else {
            item.Subitems[3].Text = "This is bad";
            }
        }

这是请求方法

public bool Request(string url, string path, string host)
    {
        HttpRequest httpRequest = new HttpRequest();
        //a lot if code with httpRequest 
        if (result == "good")
            return true;
        else
            return false;
    }

所以当我在列表中放入 20 个项目并运行此代码时,此代码不会有任何错误关闭应用程序,因此我必须添加任务以使其在不关闭应用程序的情况下运行。

所以我这样做了

foreach (ListViewItem item in list.Items)
        {
         await Task.Run(() => {
            string url, path, host;
            url = item.SubItems[0].Text; // example "www.google.com/"
            path =  item.SubItems[1].Text; // example = "login/"
            host = (item.SubItems[2].Text); // example = "123.123.123:232";
            bool ping = Request(url, path, host);
            if (ping) {
            item.Subitems[3].Text = "This is good";
            } else {
            item.Subitems[3].Text = "This is bad";
            }
          }
        }

但它给了我这个错误 当前线程必须设置为单线程单元 (STA)

【问题讨论】:

标签: c# winforms


【解决方案1】:

您无法从后台线程访问 UI 元素(即,在 Task.Run 中运行的代码)。

foreach (ListViewItem item in list.Items)
{
  string url, path, host;
  url = item.SubItems[0].Text; // example "www.google.com/"
  path =  item.SubItems[1].Text; // example = "login/"
  host = (item.SubItems[2].Text); // example = "123.123.123:232";

  var result = await Task.Run(() => {
    bool ping = Request(url, path, host);
    if (ping) {
      return "This is good";
    } else {
      return "This is bad";
    }
  });
  item.Subitems[3].Text = result;
}

【讨论】:

  • 查看我的代码后,我发现我使用 Clipboard.setText() 。我删除它但仍然给我错误所以我使用你的代码和它的工作谢谢(:
【解决方案2】:

当您不从 UI 线程调用 UI 内容时,您无法更改它。为了从另一个线程执行此操作,您需要从 Forms 调度程序中调用您的方法,如下所示:

this.Invoke(new MethodInvoker(() => 
{ 
      if (ping) {
         item.Subitems[3].Text = "This is good";
      } else {
         item.Subitems[3].Text = "This is bad";
      }
}));

//**this** is the form you want to update

还要检查这个问题,它也涵盖了这个问题: Invoke in Windows Forms

【讨论】:

  • 我已经尝试过了,它也给出了同样的错误。
  • 确保在访问 UI 的每一行代码中都使用这个
猜你喜欢
  • 2014-01-22
  • 2017-03-05
  • 2015-07-10
  • 2016-10-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多