2

I'm trying to apply thread s in a method which sets some properties. but after applying threading the method stops setting the values. My code :

Class 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;
}

calling:

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;

Before applying Thread all the values were setting properly but now all their values are set to 0.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Pranab
  • 382
  • 3
  • 10
  • What's the point of doing it in a separate thread? Seems that you need to wait for your thread to finish before assigning the *lblTotalRecords*. – thepirat000 Feb 23 '14 at 02:54

2 Answers2

1

Your problem is that you're trying to read numOfResults and the other variables right after the MyThread.Start(); call. The thread, however, could be in any one of the several possible thread states at this point - it may even be finished, although that's probably the least likely outcome.

When you try to get data about the completion of a thread you have a few options:

  • Use BackgroundWorker - it has an event that signals that the thread is done with its work. It's also simple to use.
  • Create a dedicated class that implements the thread function and also declares an event when it's done.

Using BackgroundWorker is likely the simpler solution in your scenario (since you're trying to update Label controls). The other solution is something like this:

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
    }
}

Here are a few other SO links with more detail (no point in repeating them so I only link them here):

Community
  • 1
  • 1
xxbbcc
  • 16,930
  • 5
  • 50
  • 83
  • thank you very much for your time and suggestion. but i'm still confused how can i get the values the properties ? Please guide me. – Pranab Feb 23 '14 at 02:50
  • thank you very much. these links helped me a lot. Thank you once again – Pranab Feb 24 '14 at 00:43
1

Use the MyThread.Join() method to wait for the thread to finish. Join is a blocking function and wait till completion. You can provide timeout duration to Join after which it will yield.

rajibdotnet
  • 1,498
  • 2
  • 17
  • 29