c# - 无法在设置某些类属性的方法中进行线程化

标签 c# multithreading

我正在尝试在设置一些属性的方法中应用线程。但应用线程后,该方法停止设置值。我的代码:

类Page.cs

public int numOfResults { get; private set; }

public int perPage { get; private set; }

public int pageCount  { get; private set; }

public void pageResults()
{
    HtmlWeb htmlWeb = new HtmlWeb();
    HtmlDocument document = htmlWeb.Load(this.url);

    var totalResults = document.DocumentNode
                               .Descendants("div")
                               .Where(x => x.Attributes.Contains("class") &&
                                           x.Attributes["class"].Value.Contains("result-totals"));

    string totalPages = string.Empty;

    foreach (var result in totalResults)
    {
        if (result.InnerHtml != null)
        {
            totalPages = result.InnerHtml;
            totalPages = totalPages.Substring(totalPages.LastIndexOf("f") + 1, 4);
            numOfResults = Convert.ToInt32(totalPages.Trim());
        }
    }

    var resultsSet = document.DocumentNode
                             .Descendants("div")
                              .Where(x => x.Attributes.Contains("class") &&
                                          x.Attributes["class"].Value.Contains("business-container-inner"));

    perPage = 0;
    foreach (var result in resultsSet)
        if (result.InnerHtml != null)
            perPage++;

    pageCount = (numOfResults / perPage) + 1;
}

调用:

Pages htmlDoc = new Pages(url);
Thread MyThread = new Thread(htmlDoc.pageResults);
MyThread.Start();
lblTotalRecords.Text = "Records Found : " + htmlDoc.numOfResults.ToString();
lblTotalRecords.Visible = true;
lblTotalPages.Text = "Pages Found : " + htmlDoc.pageCount.ToString();
lblTotalPages.Visible = true;

在应用线程之前,所有值都已正确设置,但现在所有值都设置为 0。

最佳答案

您的问题是您试图在 MyThread.Start(); 调用之后立即读取 numOfResults 和其他变量。然而,该线程可以是几种可能的 thread states 中的任何一种。在这一点上 - 它甚至可能已经完成,尽管这可能是最不可能的结果。

当您尝试获取有关线程完成情况的数据时,您有几个选择:

  • 使用BackgroundWorker - 它有一个事件表明线程已完成其工作。使用起来也很简单。
  • 创建一个专用类来实现线程函数,并在完成时声明一个事件。

使用 BackgroundWorker 可能是您场景中更简单的解决方案(因为您正在尝试更新 Label 控件)。另一种解决方案是这样的:

public class MyThreadWorker
{
    public event EventHandler<MyDoneEventArgs> Done;

    // TODO set input parameters through constructor or public properties

    public void DoWork ()
    {
        // TODO process work
        // TODO raise Done event
    }
}

这里有一些其他更详细的 SO 链接(没有必要重复它们,所以我只在这里链接它们):

关于c# - 无法在设置某些类属性的方法中进行线程化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21963434/

相关文章:

c# - 将 C# 反射代码移植到 Metro-Ui

windows - 等待事件是否会受到虚假唤醒的影响?

multithreading - 混合线程、 fork 和互斥锁,我应该注意什么?

完成共同工作后取消 POSIX 线程

c# - XElement 获取所有子元素节点名称和值

c# - Winrt Hubsection 中的引用控件

c# - 我如何在 C# 中加密 web.config 变量

c++ - 从父线程继承全局值

ios - observeValueForKeyPath 总是从主线程调用吗?

java - JAVA 中的 WCF 服务