2009-12-04 37 views
9

Tôi đang cố gắng hiển thị không đồng bộ dữ liệu trong bảng cập nhật trên trang web nơi các tác vụ truy xuất dữ liệu mất các thời điểm khác nhau. Tôi muốn cập nhật từng bảng để hiển thị dữ liệu trên trang sau mỗi tác vụ kết thúc.ASP.Net: Bảng cập nhật không đồng bộ Tải với hai bảng cập nhật

Tuy nhiên, bất kể tôi thử làm gì, tất cả các Bảng cập nhật đều thay đổi nội dung của họ sau khi tác vụ cuối cùng đã hoàn thành.

Ví dụ:

Tôi có hai nhiệm vụ:

  • Một mà cố gắng để cập nhật một nhãn trong UpdatePanel1 sau 5 giây
  • Một mà cố gắng để cập nhật một nhãn trong UpdatePanel2 sau 10 giây

Kết quả mong đợi là hav e chỉ nhãn trong UpdatePanel1 thay đổi sau 5 giây, tuy nhiên, cả hai cập nhật bảng cập nhật cùng một lúc, lúc 10 giây.

Cả hai bảng cập nhật đều được đặt thành updatemode = "Có điều kiện" và chúng được yêu cầu gửi lại từ javascript của khách hàng. Dưới đây là danh sách đầy đủ của ví dụ trên.

Tôi thiếu gì ở đây? Làm thế nào để tôi nhận được một bảng cập nhật để tải, và sau đó khác, có cả hai nhiệm vụ chạy không đồng bộ?

Cảm ơn,

TM

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> 

C#:

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(); 
    } 
} 

Trả lời

0

tôi nghi ngờ rằng bạn không gọi này là không đồng bộ như bạn nghĩ b/c của chuỗi tham gia. Có vẻ như bạn đang nói về khối OnPrerender cho đến khi chuỗi 2 chấm dứt. Vì cả 2 và 1 đều được gọi từ cùng một phương thức, bạn bị chặn cho đến khi cả hai được thực hiện. Nếu bạn ném vào một số writelines để xem khi mọi thứ đang được gọi, nó có thể trở nên dễ dàng hơn một chút để xem những gì đang xảy ra.

Tôi cũng nghi ngờ văn bản trên 1 sẽ không thực sự cập nhật cho đến khi hiển thị trước hoàn tất từ ​​những gì tôi biết. ASP.NET truyền thống, không có gì được gửi lại cho khách hàng cho đến khi sau khi hoàn tất trước. Nhưng tôi không biết nhiều về bảng cập nhật, vì vậy tôi có thể nói chuyện rác rưởi trên bảng điều khiển đó và dự đoán sẽ bị đánh dấu ...

0

Các kết nối trong trình xử lý trước khi kết xuất của bạn đang chặn hiển thị từ quay lại máy khách . Thay vì những gì bạn có, tôi nghi ngờ rằng bạn có thể làm một cái gì đó giống như thay vì điều này:

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

Đó là mã có tác dụng phụ không mong muốn của bị lệ thuộc vào hiểu biết mà chủ đề sẽ trở lại đầu tiên, mặc dù. Tuy nhiên, nếu bạn chỉ cố gắng tìm ra cách gửi sự kiện từ máy chủ đến máy khách (và html 5 là một tùy chọn), tôi khuyên bạn nên xem xét server-sent events (hoặc ổ cắm web nếu bạn yêu cầu truyền thông song công toàn bộ).Nếu html 5 không phải là một tùy chọn, tôi tin rằng bạn có thể sử dụng một số hacks javascript để mô phỏng các ổ cắm web. Bạn có thể đọc về một số trong số đó herehere.

chỉnh sửa: thêm liên kết cho phi html 5 lựa chọn thay thế

0

Bạn có thể sử dụng .NET 4.5 hoặc bạn bị hạn chế với các phiên bản trước đó? v4.5 có rất nhiều tính năng mới giúp tạo các phương thức không đồng bộ khá thẳng về phía trước mà không phải lo lắng về quản lý luồng. Liên kết này có một lời giải thích tốt về làm thế nào để thực hiện một phương pháp không đồng bộ với Task nhiệm vụ mới và async/await nhà khai thác: Working with Asynchronous Operations in ASP.NET 4.5 Web Forms

Về cơ bản bạn chỉ muốn có để tạo ra một Task cho mỗi phương pháp có trách nhiệm cập nhật các updatepanel và bắn nó lên trên tải trang. Khi hoàn thành, mỗi tác vụ có thể ngủ trong 5 hoặc 10 giây trước khi gọi chính nó để cung cấp cho bạn hiệu ứng bạn đang theo dõi.

0

Thay vào đó bạn có thể sử dụng 2 điều khiển hẹn giờ, một với khoảng thời gian 5000 và khác với khoảng 10.000

1

Chỉ cần đặt một thẻ kích hoạt bên trong mỗi UpdatePanel trỏ đến một asp: Timer và thiết lập khoảng thời gian 5000 và 10000 mili giây.

Dưới đây là giải pháp mà bạn yêu cầu, sử dụng UpdatePanel, nhưng chăm sóc bởi vì mỗi 5 đến 10 giây có một PostBack sa thải vì Timer:

tôi khuyên bạn nên sử dụng javascript hoặc jQuery để tránh 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> 

C#

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!"; 
     } 
    } 
} 
Các vấn đề liên quan