1

我想在单击按钮时填充一个位于更新面板内的 Gridview。目前,gridview 正在被填充,但没有显示在屏幕上。我错过了什么?下面是我正在使用的代码:

  public delegate void BindGrid_Delegate();
  protected void btnSearch_Click(object sender, EventArgs e)
  {
        try
        {
            // databind of all the controls
            BindGrid_Delegate bd = new  BindGrid_Delegate(BindGrid);
            IAsyncResult ar = bd.BeginInvoke(null, null); //invoking the method
        }
        catch (Exception ex)
        {
            ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "PageException", "alert('" + ex.Message + "');", true);
        }
  }

  private void BindGrid()
  {
      try
      {
          DataSet ResultDataSet = GetData();
          gvShowResult.DataSource = ResultDataSet; 
          gvShowResult.DataBind();
          UpdatePanel2.Update();
      }
      catch (Exception ex)
      {
          ScriptManager.RegisterClientScriptBlock(this, this.GetType(), "PageException", "alert('" + ex.Message + "');", true);
      }
  }

更新面板的更新模式是有条件的。我会很感激任何帮助。

4

2 回答 2

0

问题可能是您在非 UI 线程上调用DataBind()和。Update()UI 控件只能在创建它们的线程上进行修改。

您仍然可以GetData()在单独的线程中调用您的方法,例如使用Tasks

在你的btnSearch_Click方法中:

Task.Factory
    .StartNew(() => GetData())
    .ContinueWith(t => 
    {
        gvShowResult.DataSource = t.Result; 
        gvShowResult.DataBind();
        UpdatePanel2.Update();
    }, TaskScheduler.FromCurrentSynchronizationContext());

这会调用GetData()一个单独的线程并在 UI 线程上执行延续。

于 2013-05-13T07:57:32.133 回答
0

我认为您的代码存在多个问题。首先,您不会让 ASP .Net 知道您希望将异步方法作为请求的一部分执行。在您的代码中,请求在调用 bd.BeginInvoke() 后返回,而它应该在对 BindGrid 的异步调用完成后返回。

第二个问题是当您异步调用 BindGrid() 方法时,您的代码中没有异步 I/O,因此在检索数据时您没有释放任何 ASP .Net 线程。您只是在延迟调用 BindGrid()。这篇文章应该可以帮助您解决上述问题。

如果使用 .Net 4.5 是一个选项,您应该尝试使用 async 和 await 对创建异步行为。查看这篇文章,它解释了如何在 ASP .Net MVC 中做到这一点。

于 2013-05-13T08:23:22.873 回答