asp:DataGrid 可见性与异步? [英] asp:DataGrid visibility with async?

查看:23
本文介绍了asp:DataGrid 可见性与异步?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

这里有一个真正的异步谜题,我已经折腾了两天了.

我正在修改一些长期运行的报告以使其异步,但我可以用非常简单的代码来演示我的问题.

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

这是标记:

<form runat="服务器"><asp:datagrid ID="grid"visible="false" Runat="server"></asp:datagrid></表单>

在代码隐藏中,此代码有效:

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

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

在@Page 指令中添加 Async="True"用这个替换 Page_Load

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

网格未呈现.请注意,即使委托中没有 await,我也使用了 async 关键字.我尝试了几件事,结果都一样:

  1. 添加一个 await Task.Delay(...)
  2. 删除 async 关键字并返回 Task.FromResult(0)

我已经覆盖并检测了页面生命周期事件,以查看网格何时填充以及其可见性如何变化.这是我看到的输出:

OnPreInit: Visible=False Rows=0 Thread=63OnInit: Visible=False Rows=0 Thread=63OnInitComplete:可见=假行=0线程=63OnPreLoad:可见=假行=0 线程=63OnLoad:可见=假行=0线程=63OnLoadComplete:可见=假行=0线程=63OnPreRender:可见 = 假行 = 0 线程 = 63异步 1:可见 = 假行 = 0 线程 = 63异步 2:可见 = 真行 = 1 线程 = 63OnPreRenderComplete:可见 = 真行 = 1 线程 = 63OnSaveStateComplete: Visible=True Rows=1 线程=63渲染 1:可见 = 真行 = 1 线程 = 63渲染 2:可见 = 真行 = 1 线程 = 63

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

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

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

</表单>

似乎是 asp:datagrid 本身的 visible="false" 搞砸了.

我做错了什么?

解决方案

假设 RegisterAsyncTask 返回一个 promise,试试

this.RegistreAsyncTask(异步 () =>{返回新字典<字符串,字符串>(){{ "col1", "value1";}};}).then(dataSource => {grid.DataSource = dataSource; grid.visible = true})

想法是 async 在不同的后台线程中运行,而 PromiseUI 线程 中解决(与类似的 android 概念有关)

.NET 4.5.2, IIS 8.5 on Windows 8.1 x64. I have a single ASP.NET web site at /localhost/.

I've got a real async-puzzle here that I've been wrestling with for two days now.

I'm reworking some long-running reports to be async, but I can demonstrate my problem with very simple code.

I have an asp:DataGrid on my page that I've initially set visible="false". It should only be visible if it is populated. My problem is, if the code that populates it is async I don't see the grid!

Here's the markup:

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

In the code-behind, this code WORKS:

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

Now if I make two changes:

Add Async="True" to the @Page directive Replace Page_Load with this

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

The grid is not rendered. Note that I've used the async keyword even though there is no await in the delegate. I have tried several things, all with the same result:

  1. Add an await Task.Delay(...)
  2. Remove the async keyword and Return Task.FromResult(0)

I have overridden and instrumented the page lifecycle events to see when the grid is populated and how its visiblity changes. This is the output I see:

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" and "2" are on either side of the grid population inside the delegate. You can see the grid is getting a row and its visibility gets true, yet it isn't rendered. If I populate the grid with my first code sample, synchronously, all is well.

Another note: I can enclose the grid in another control to make it work:

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

It seems to be the visible="false" on the asp:datagrid itself that screws this up.

What am I doing wrong?

解决方案

Assuming RegisterAsyncTask returns a promise, try

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

Idea being the async runs in a different background thread and the Promise is resolved in the UI thread (relating to similar android concepts)

这篇关于asp:DataGrid 可见性与异步?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆