在过去的几天里,我一直在努力学习如何使用 ASP.NET Web 窗体和多线程,方法是使用两者构建一个简单的小程序,我一直在努力解决不同线程和 UI 之间的交互方面。
我已经在其他一些问题中解决了一些多线程问题(并且在 waaaaaay 之后也了解到 Web 表单和 WPF 不是一回事)但现在我在寻找基于获取的数据更新 UI 元素的最佳方法时遇到了麻烦在多个线程中。
这是我的代码:
默认.aspx
public partial class _Default : System.Web.UI.Page
{
private NlSearch _search;
private static int _counter = 0;
private static SortedList<long, SearchResult> resultsList = new SortedList<long, SearchResult>();
protected void Page_Load(object sender, EventArgs e)
{
_search = new NlSearch();
}
protected void AddSearchMethod(object sender, EventArgs e)
{
var text = SearchForm.Text;
new Task(() => MakeRequest(text));
}
protected void UpdateMethod(object sender, EventArgs e)
{
resultsLabel.Text = "";
foreach (var v in resultsList.Values)
{
resultsLabel.Text += v.SearchTerm + ": " + v.Count + " occurances<br/>";
}
}
protected void ClearSearchMethod(object sender, EventArgs e)
{
resultsLabel.Text = "";
resultsList.Clear();
}
protected void MakeRequest(string text)
{
_counter++;
SearchResult s = new SearchResult
{
SearchTerm = text,
Count = _search.MakeRequests(text)
};
resultsList.Add(_counter, s);
}
}
我已经尝试了很多相同的基本版本。NlSearch.MakeRequest(由 MakeRequests 调用)将 HTTP POST 请求发送到模仿搜索栏输入的外部网站,然后从标记中提取一个整数,指示返回了多少结果。
当前的简单 UI 围绕着一个 SearchForm 文本字段、一个“添加搜索”按钮、一个“更新标签”按钮、一个“清除搜索”方法和一个显示结果的 ResultsLabel。AddSearch 按钮创建一个调用 MakeRequest 的新任务,该任务调用该方法来发送 HTTP 请求,然后将结果按发送顺序存储在静态排序列表中。
所以现在理想情况下,在一个好的 UI 中,我只想在每次线程返回时更新标签,但是我尝试使用 ContinueWhenAll 和其他一些任务函数,问题似乎是其他线程没有能力改变用户界面。
我还尝试在页面加载时运行一个新线程,每隔几秒更新一次标签,但这同样失败了。
因为我无法正确实现这一点,我不得不使用“更新标签”按钮,它实际上只是告诉标签显示静态列表中的当前内容。我真的很想摆脱这个按钮,但我不知道如何让我的线程进行 UI 更改。