我有一个简单的ASP.NET小程序,我正在尝试学习基本的多线程以使其运行更顺畅。
假设我有一个连接到以下方法的按钮:
private NlSearch search;
protected void SearchButtonClick(object sender, EventArgs e)
{
int resultCount = search.MakeRequests(SearchForm.Text);
resultsLabel.Text += SearchForm.Text + ": " + resultCount.ToString() + " occurances";
}
所有MakeRequests都会发出POST请求,在第三方网站上进行搜索,并从响应中获取结果数。然后将搜索词和结果数添加到页面中。
但是,如果我在第一次搜索响应之前做了一些提交新搜索的操作,它只会中断原始搜索,只有最近的搜索会将结果写入标签。
我知道有一种方法可以用C#线程来做到这一点,但我无法弄清楚如何正确使用任务来做到这一点。我尝试将方法的主体放入第二个方法,没有参数,然后我用来创建和运行任务,但这并没有改变行为,所以我认为我使用的任务不正确。
任何帮助或建议都将不胜感激,谢谢。
编辑:我到目前为止所尝试的内容:两个答案在检索值时似乎“有效”,但出于某种原因,由于某种原因,它们实际上都没有将它们添加到标签中。例如protected void NewSearchClick(object sender, EventArgs e)
{
new Thread(() => MakeRequest(SearchForm.Text)).Start();
}
和
protected void MakeRequest(string text)
{
int resultCount = search.MakeRequests(text);
if (resultsLabel != null) resultsLabel.Text += text + ": " + resultCount + " occurances";
}
似乎检索了值,但标签没有改变。
答案 0 :(得分:3)
在WPF应用程序中,您应该同时使用线程和Dispatcher,因为只有UI线程可以写入标签。更具体地说,您应该使用调度程序作为回调来在任务完成时更新UI中的任何内容:
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:使用Dispatcher而不仅仅是线程
Edit2:同时使用Dispatcher和线程
答案 1 :(得分:1)
我会使用.NET Task来管理线程池。
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";
});
}