【问题标题】:Backgroundworker blocks PageloadBackgroundworker 阻止页面加载
【发布时间】:2017-05-16 16:11:38
【问题描述】:

我正在尝试从 Entity Framework 加载大量数据。该请求大约需要一分钟并阻止页面加载。由于这对于较大的查询变得不合理,我想我会尝试使用后台线程或类似的东西。经过一段时间的研究,我发现了一个叫做 BackgroundWorker 的东西。我试图实现这一点,但它不起作用。 这是我的代码:

  void Page_LoadComplete(object sender, EventArgs e)
    {
        InitializeBackgroundWorker();
    }

    private void InitializeBackgroundWorker()
    {
        bw = new BackgroundWorker {WorkerReportsProgress = true};


        bw.DoWork += (sender, e) => e.Result = (List<object>)e.Argument;
        bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
        bw.RunWorkerAsync(doSomething());

        bw.RunWorkerCompleted += (sender, e) =>
        {
            AjaxWaitBox.Text = "Completed";
        };
    }
        private readonly Func<List<object>> doSomething = () =>
    {

        var list = ObjectFactory.Container.GetInstance<IActivityRepository>().GetAllActivitiesNotFiltered(ContentReference.RootPage);
        var count = list.Count;
        int i = 0;
        foreach (var item in list)
        {
            i++;
            Console.WriteLine("-(DoWork)->" + i);
            double percentage = (Convert.ToDouble(i) / Convert.ToDouble(count)) * 100;
            Console.WriteLine("-(DoWork.percentage)-> " + percentage);
            bw.ReportProgress((int)percentage);
        }
        return list;
    };
    private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
        AjaxWaitBox.Text = e.ProgressPercentage.ToString();
    }

起初我在 OnInit 方法中调用了 InitializeBackgroundWorker()。然后页面加载了大约一分钟,然后我的文本框的值(用于显示查询进度)是:“完成”。然后我将调用移至 Page_LoadComplete 但结果仍然相同。我在这里想念什么?我是否还需要包括 async/await 运算符或什么?

【问题讨论】:

    标签: c# multithreading async-await task backgroundworker


    【解决方案1】:

    BackgroundWorker 仅用于释放 UI 线程。由于您使用的是 ASP.NET,因此您没有 UI 线程。

    ASP.NET 处理 HTTP 请求和响应。 “页面”抽象(不幸的是)看起来像一个 UI 框架,但它不是

    因此,您需要根据 HTTP 请求和响应来考虑您的问题,因为这就是实际发生的情况。每个请求只有一个响应,因此无法“发送无数据页面响应”,然后更改它为“发送有数据页面响应”。

    相反,您需要做的是发送一个没有数据的页面响应,然后让该页面使用 AJAX(或UpdatePanel)等技术对实际数据发出单独的请求,并在页面中填写那个。

    【讨论】:

      【解决方案2】:

      您正在同步调用 doSomething()。 你应该做这样的事情(未经测试):

      private void InitializeBackgroundWorker()
      {
          System.ComponentModel.BackgroundWorker bw = new System.ComponentModel.BackgroundWorker { WorkerReportsProgress = true };
      
      
          bw.DoWork += (sender, e) => e.Result = doSomething();
          bw.ProgressChanged += new ProgressChangedEventHandler(bw_ProgressChanged);
          bw.RunWorkerAsync();
      
          bw.RunWorkerCompleted += (sender, e) =>
          {
              AjaxWaitBox.Text = "Completed";
          };
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-08
        • 1970-01-01
        • 1970-01-01
        • 2014-02-05
        • 2011-01-13
        • 2021-11-01
        • 1970-01-01
        相关资源
        最近更新 更多