How can you use threading to send multiple web req

2019-07-23 12:47发布

问题:

I have a simple ASP.NET applet, and I'm trying to learn basic multithreading to make it run more smoothly.

Let's say I have a button hooked up to the following method:

private NlSearch search;

protected void SearchButtonClick(object sender, EventArgs e)
    {

        int resultCount = search.MakeRequests(SearchForm.Text);
        resultsLabel.Text += SearchForm.Text + ": " + resultCount.ToString() + "     occurances";
    }

All MakeRequests does is issue a POST request to do a search on a 3rd party website and grabs the number of results from the response. The search term along with the number of results is then added to the page.

However if I were to do something like submit a new search before the first search has responded, it will simply interrupt the original search and only the most recent search will write it's results to the label.

I understand there's a way to do this with C# threading, but I can't figure out how to use tasks correctly to do this. I tried putting the body of the method into a second method with no arguments that I then used to create and run a task, but this did not change the behavior so I think I was using tasks incorrectly.

Any help or advice would be appreciated, thanks.

EDIT: What I've tried so far: both answers seemed to 'work' at retrieving values but for some reason neither actually added them to the label for some reason. For example

protected void NewSearchClick(object sender, EventArgs e)
    {
        new Thread(() => MakeRequest(SearchForm.Text)).Start();
    }

and

protected void MakeRequest(string text)
    {
            int resultCount = search.MakeRequests(text);
            if (resultsLabel != null) resultsLabel.Text += text + ": " + resultCount + "     occurances";
    }

seemed to retrieve the value but the label does not change.

回答1:

In a WPF app, you should use both threads and Dispatcher, because only the UI thread can write to a label. More specifically, you should use the dispatcher as a callback to update anything in the UI when a task is complete:

protected void SearchButtonClick(object sender, EventArgs e)
{
    new Thread(() => MakeRequest(SearchForm.Text)).Start();
}

protected void MakeRequest(string text)
{
    int resultCount = search.MakeRequests(text);

    // tell UI thread to update label
    Dispatcher.BeginInvoke(new Action(() =>
            {
                resultsLabel.Text += text + ": " + resultCount + "     occurances";
            }));
}

Edit1: use Dispatcher not just threads

Edit2: use both Dispatcher and threads



回答2:

I would use .NET Task as they manage the thread pool for you.

LINK: Task [Managed parallelism]

protected void SearchButtonClick(object sender, EventArgs e)
{
   var text = SearchForm.Text;
   Task.Factory.StartNew(() => 
   {
      var resultCount = search.MakeRequests(text);
      resultsLabel.Text += text + ": " + resultCount + "     occurances";
   });
}