asp:使用异步的DataGrid可见性?

时间:2015-07-14 14:39:40

标签: c# asp.net async-await .net-4.5.2

.NET 4.5.2,Windows 8.1 x64上的IIS 8.5。我在/ localhost /有一个ASP.NET网站。

我在这里遇到了一个真正的异步谜题,现在我已经摔跤了两天。

我正在将一些长时间运行的报告重新编写为异步,但我可以使用非常简单的代码来演示我的问题。

我的页面上有一个asp:DataGrid,我最初设置为visible =“false”。它应该只有在填充时才可见。我的问题是,如果填充它的代码是异步的,我看不到网格!

这是标记:

<body>
    <form runat="server">
        <asp:datagrid ID="grid" visible="false" Runat="server"></asp:datagrid>
    </form>
</body>

在代码隐藏中,此代码工作:

void Page_Load()
{
    grid.DataSource = new Dictionary<string, string>()
    {
        { "col1", "value1" }
    };
    grid.DataBind();
    grid.Visible = true;
}

现在,如果我进行两项更改:

将@ Async =“True”添加到@Page指令中 用这个替换Page_Load

void Page_Load()
{
    this.RegisterAsyncTask(new PageAsyncTask(async () =>
        {
            grid.DataSource = new Dictionary<string, string>()
            {
                { "col1", "value1" }
            };
            grid.DataBind();
            grid.Visible = true;
        }));
}

不会渲染网格。请注意,即使委托中没有等待,我也使用了async关键字。我尝试了几件事,都有相同的结果:

  1. 添加await Task.Delay(...)
  2. 删除async关键字并返回Task.FromResult(0)
  3. 我已经覆盖并检测了页面生命周期事件,以查看网格何时填充以及其可见性如何变化。这是我看到的输出:

    OnPreInit: Visible=False Rows=0 Thread=63
    OnInit: Visible=False Rows=0 Thread=63
    OnInitComplete: Visible=False Rows=0 Thread=63
    OnPreLoad: Visible=False Rows=0 Thread=63
    OnLoad: Visible=False Rows=0 Thread=63
    OnLoadComplete: Visible=False Rows=0 Thread=63
    OnPreRender: Visible=False Rows=0 Thread=63
    Async 1: Visible=False Rows=0 Thread=63
    Async 2: Visible=True Rows=1 Thread=63
    OnPreRenderComplete: Visible=True Rows=1 Thread=63
    OnSaveStateComplete: Visible=True Rows=1 Thread=63
    Render 1: Visible=True Rows=1 Thread=63
    Render 2: Visible=True Rows=1 Thread=63
    

    “Async 1”和“2”位于委托内部网格填充的两侧。您可以看到网格正在变为一行并且其可见性变为真,但它未呈现。如果我使用我的第一个代码示例填充网格,同步,一切都很好。

    另一个注意事项:我可以将网格封装在另一个控件中以使其工作:

    <body>
        <form runat="server">
            <div id="container" visible="false" runat="server">
                <asp:datagrid ID="grid" Runat="server"></asp:datagrid>
            </div>
        </form>
    </body>
    

    似乎是asp:datagrid本身的visible =“false”会搞砸了。

    我做错了什么?

2 个答案:

答案 0 :(得分:0)

尝试将Grid放在UpdatePanel中,并在UpdatePanel的OnLoad事件上调用async方法(以将数据加载到Grid中并管理其可见性)

答案 1 :(得分:0)

假设RegisterAsyncTask返回一个承诺,请尝试

this.RegistreAsyncTask(
 async () => 
    {
       return new Dictionary<string, string>(){
         { "col1", "value1" }
       };
    }
).then(dataSource => {grid.DataSource = dataSource; grid.visible = true})

作为async的想法在不同的后台线程中运行,并且PromiseUI thread中得到解决(与相似的android概念有关)