ASP.Net: панель асинхронного обновления Загрузка с помощью двух панелей обновления

9

Я пытаюсь асинхронно отображать данные в панелях обновления на веб-сайте, где задачи поиска данных занимают разные времена. Я хотел бы обновить каждую панель, чтобы отобразить данные на странице после завершения каждой задачи.

Однако, независимо от того, что я пытаюсь, все панели обновления меняют свой контент после завершения последней задачи.

Например:

У меня есть две задачи:

  • Тот, кто пытается обновить метку в UpdatePanel1 через 5 секунд
  • Тот, кто пытается обновить метку в UpdatePanel2 через 10 секунд

Ожидаемый результат состоит в том, чтобы изменить только метку в UpdatePanel1 через 5 секунд, однако обе обновления обновляются одновременно, через 10 секунд.

Обе панели обновления установлены в updatemode = «Условные», и им сообщают об обратной передаче с javascript клиента. Ниже приведен полный список приведенного выше примера.

Что мне здесь не хватает? Как получить одну панель обновления для загрузки, а затем другую, обе задачи выполняются асинхронно?

Спасибо,

ТМ

ASPX:

<%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs"
    Inherits="_Default"%>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body onload="partialPostback();">
    <script language="JavaScript" type="text/javascript">

    function partialPostback() {
        __doPostBack('UpdatePanel1', '');
        __doPostBack('UpdatePanel2', '');
    }
    </script>

    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"/>

        5 sec:
        <asp:UpdatePanel ID="UpdatePanel1" runat="server"
         UpdateMode="Conditional" OnLoad="UpdatePanel1_Load">
            <ContentTemplate>
                <asp:Label ID="Label2" runat="server" Text="Label"/><br />
            </ContentTemplate>
        </asp:UpdatePanel><br />

        10 sec:
        <asp:UpdatePanel ID="UpdatePanel2" runat="server"
         UpdateMode="Conditional" OnLoad="UpdatePanel2_Load">
            <ContentTemplate>
                <asp:Label ID="Label1" runat="server" Text="Label"/><br />
            </ContentTemplate>
        </asp:UpdatePanel>
    </form>
</body>
</html>

С #:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Threading;

public partial class _Default : System.Web.UI.Page
{
    Thread t1;
    Thread t2;

    protected override void OnPreRender(EventArgs e)
    {
        if (t1 != null)
        { t1.Join(); }

        if (t2 != null)
        { t2.Join(); }

        base.OnPreRender(e);
    }

    protected void Page_Load(object sender, EventArgs e)
    { }

    protected void UpdatePanel1_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            ThreadStart tstart = new ThreadStart(DoWork1);
            t1 = new Thread(tstart);
            t1.IsBackground = true;
            t1.Start();
        }
    }

    protected void UpdatePanel2_Load(object sender, EventArgs e)
    {
        if (IsPostBack)
        {
            ThreadStart tstart = new ThreadStart(DoWork2);
            t2 = new Thread(tstart);
            t2.IsBackground = true;
            t2.Start();
        }
    }

    private void DoWork1()
    {
        Thread.Sleep(5000);
        this.Label2.Text = "Done in 5 sec!";
        this.UpdatePanel1.Update();
    }

    private void DoWork2()
    {
        Thread.Sleep(10000);
        this.Label1.Text = "Done in 10 sec!";
        this.UpdatePanel2.Update();
    }
}
    
задан Owen Blacker 04.12.2009 в 17:28
источник

5 ответов

1

Просто поместите тег Trigger внутри каждой UpdatePanel, указав на asp: Timer и установите интервал до 5000 и 10000 miliseconds.

Ниже вы найдете решение, использующее UpdatePanel, но будьте осторожны, потому что каждые 5 и 10 секунд PostBack запускается для таймера:

Я рекомендую использовать javascript или jQuery, чтобы избежать PostBacks.

ASPX:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs"
    Inherits="WebApplication1.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"/>

        5 sec:
        <asp:UpdatePanel ID="UpdatePanel1" runat="server">
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Timer1" EventName="Tick"/>
            </Triggers>
            <ContentTemplate>
                <asp:Label ID="Label2" runat="server" Text="Label"/><br />
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:Timer ID="Timer1" runat="server" Interval="5000"
            OnTick="Timer1_Tick"/><br />

        10 sec:
        <asp:UpdatePanel ID="UpdatePanel2" runat="server">
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="Timer2" EventName="Tick"/>
            </Triggers>
            <ContentTemplate>
                <asp:Label ID="Label1" runat="server" Text="Label"/><br />
            </ContentTemplate>
        </asp:UpdatePanel>
        <asp:Timer ID="Timer2" runat="server" Interval="10000"
            OnTick="Timer2_Tick"/> 
    </form>
</body>
</html>

С #

using System;

namespace WebApplication1
{
    public partial class Default : System.Web.UI.Page
    {
        protected void Timer1_Tick(object sender, EventArgs e)
        {
            this.Label2.Text = "Done in 5 sec!";
        }

        protected void Timer2_Tick(object sender, EventArgs e)
        {
            this.Label1.Text = "Done in 10 sec!";
        }
    }
}
    
ответ дан Stephan 14.08.2013 в 01:08
0

Я подозреваю, что вы не называете это асинхронно, как вы думаете, b / c потока присоединяется. Похоже, вы в основном говорите блок OnPrerender, пока поток 2 не завершится. Поскольку и 1, и 2 вызываются одним и тем же способом, вы блокируетесь до тех пор, пока оба не будут выполнены. Если вы набросаете некоторые сценарии, чтобы увидеть, когда что-то происходит, может быть немного легче увидеть, что происходит.

Я также подозреваю, что текст на 1 не будет действительно обновляться до тех пор, пока прерандер не завершится из того, что я знаю. Традиционный ASP.NET, ничего не отправляется обратно клиенту до тех пор, пока after не завершится. Но я мало что знаю о панели обновления, поэтому я мог бы говорить об этом мусорке и предвидеть, что вы отметили ...

    
ответ дан Jim L 04.12.2009 в 17:44
0

Соединения в вашем обработчике предварительного рендеринга блокируют рендеринг от возврата к клиенту. Вместо того, что у вас есть, я подозреваю, что вы могли бы сделать что-то вроде этого:

if (t1 != null) {
    t1.join();
} else if (t2 != null) {
    t2.join();
}

Этот код имеет неудачный побочный эффект от того, чтобы быть зависимым от знания того, какой поток будет возвращаться первым.

Однако, если вы просто пытаетесь выяснить, как отправлять события с сервера на клиент (и html 5 - это вариант), я бы рекомендовал посмотреть события, отправленные сервером (или веб-сокеты, если требуется полная дуплексная связь). Если html 5 не является вариантом, я считаю, что вы можете использовать некоторые javascript-хаки для имитации веб-сокетов. Вы можете прочитать некоторые из этих здесь и .

edit: добавлены ссылки для альтернатив non-html 5

    
ответ дан kmkemp 06.04.2012 в 20:08
0

Вместо этого вы можете использовать 2 регулятора таймера, один с интервалом 5000 и другой с интервалом 10000

    
ответ дан Sanjay 19.01.2013 в 13:50
0

Можете ли вы использовать .NET 4.5 или вы ограничены более ранними версиями? v4.5 имеет множество новых функций, которые делают создание асинхронных методов довольно простым, не беспокоясь о управлении потоками. Эта ссылка имеет хорошее объяснение того, как реализовать асинхронный метод с новым Task и async / await : Работа с асинхронными операциями в ASP.NET 4.5 Веб-формы

По существу вам просто нужно создать Task для каждого метода, ответственного за обновление панели обновлений, и запустить ее при загрузке страницы. По завершении каждая задача может спать в течение 5 или 10 секунд, прежде чем называть себя, чтобы дать вам эффект, который вы после.

    
ответ дан Nathon Fowlie 30.10.2012 в 06:39