1

在过去的几天里,我一直在努力学习如何使用 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 更改。

4

4 回答 4

2

一般来说,尝试在 Web 应用程序中进行线程处理是个坏主意。Web 服务器就是为此而设计的,但应尽可能避免分离新线程或进程。虽然曾经有一种机制(也许现在仍然存在)将结果“推送”给客户,但今天有更好的解决方案可用。

您所描述的正是 AJAX 旨在解决的问题。

于 2013-07-26T16:33:41.340 回答
2

您在问题中提到了 WPF——您是否正在寻找 Windows 应用程序,例如 WinForms?我认为也许“网络表单”这个词混淆了这种情况。Web 表单只是添加了一些(好吧,很多)Microsoft 功能的网页。

听起来您正试图从代码中的线程向网页发送更新。网络不是这样工作的。如果您实际上是在尝试设计网页,我建议您通读ASP.NET 页面生命周期概述。其他答案建议使用 AJAX 功能(这是网页执行一些 JavaScript 并与 Web 服务器对话的地方)。

于 2013-07-26T16:40:26.697 回答
0

你以前听说过 AJAX 吗?我认为您是应用程序开发人员而不是 Web 开发人员的思维方式。

于 2013-07-26T16:21:53.430 回答
0

如果你想异步运行你的代码,你可能想使用Async Await关键字而不是自己管理线程。请参阅有关使用 Async 和 Await 进行异步编程的信息

不要让你的线程缠结;)

于 2013-07-26T16:28:34.103 回答