如何在 C# .net 网页上显示来自另一个线程的弹出窗口?

Posted

技术标签:

【中文标题】如何在 C# .net 网页上显示来自另一个线程的弹出窗口?【英文标题】:How to show popup from another thread on C# .net web pages? 【发布时间】:2018-11-09 10:52:46 【问题描述】:

我有一个带有母版页的 asp.net 网页。在服务器端,我有与 mssql 数据库交互的控制台应用程序(定期向数据库插入行)。在后面的网页代码中,我使用 SqlTableDependency 来捕获该操作。问题是:我认为要实现这一点,我需要无限循环中的另一个线程来“监听”并且不阻塞原始 UI 线程。我最常通过某种弹出窗口通知用户,插入已成功完成,但由于它在不同的线程上运行,它根本无法访问页面控件。我尝试了 MessageBox 和 javascript 警报,但没有成功。我做了一些研究,但只在网络表单的情况下得到了答案。有没有办法以某种方式实现这一目标?我也对另一种解决方案感兴趣,但必须在客户端通知用户。这是感兴趣的代码:

public partial class ProdData_Main : System.Web.UI.Page


  protected void Page_Load(object sender, EventArgs e)
  

        if (!IsPostBack)
        
           ThreadStart childref2 = new ThreadStart(NotifySqlChanges);
           Thread childThread2 = new Thread(childref2);
           childThread2.Start();

         else 
            //some code which is not important right now...
        
  

  public void NotifySqlChanges()
  
        string connString = getConnectionString();

        var mapper = new ModelToTableMapper<Prod_Data_Business_Object>();
        mapper.AddMapping(c => c.Value, "Value");

        using (var dep = new SqlTableDependency<Prod_Data_Business_Object>(connString, "Prod_Data_Business_Object", mapper, null, null, TableDependency.Enums.DmlTriggerType.Insert, false))
        
            dep.OnChanged += Changed;

            dep.Start();

            while (true)
            
                //here comes the infinity loop which listens for action
            
        
       // Debug.WriteLine("terminated");
        

  public void Changed(object sender, RecordChangedEventArgs<ProdData_Bus> e)
  
        var changedEntity = e.Entity;
    //here would be the perfect place to inform user
    //got no idea, how... (Controls derive from System.Web.UI thus cannot 
    //use Invoke, and ScriptManager.RegisterStartupscript not working


  

【问题讨论】:

您需要了解the request lifecycle。请求完成后,您无法向用户发送任何新数据,除非用户通过 ajax 调用或类似方式请求数据。 感谢您的澄清。我对页面生命周期感到困惑。 :) 【参考方案1】:

当您正在编写WebApplication 时,与客户进行实时互动已经是一个问题。因为 Http 不记得客户端。 所以您必须使用SignalRAjax(更简单)将此功能添加到您的webApplication。

您需要将新更改的数据(来自 mssql)存储到静态集合中(例如 static List&lt;...&gt;)。 (如果您有多个用户,最好将他们保留在Session 中)

您的线程将随时填充此集合。你还有另一个页面(我将其命名为ChangeService):

 public partial class ChangesService : System.Web.UI.Page
 
     protected void Page_Load(object sender, EventArgs e)
     
         Response.Write("Here is My changes  : blob blob blob :)");
     
 

因此,如果您需要定期获取新更改,Ajax 是您的选择;您可以定期使用Ajax 调用此页面并向您的客户展示新的更改。

但如果您想尝试SignalR,它是与每个客户端的直接连接,您可以在每次更改时通知每个用户。 (但需要更多时间才能理解)

【讨论】:

完美,我使用 ajax 让它工作。谢谢你。 :)【参考方案2】:

您可以通过两种可能的方式实现这一目标:

1) 以特定的时间间隔(可能是每秒)对服务器进行一些 ajax 调用,并相应地更新网页。

2) 使用网络套接字。检查下面的 websockets 示例实现。 https://code.msdn.microsoft.com/The-simple-WebSocket-4524921c

您可以在 Internet 上找到与 Web 套接字相关的文章。

【讨论】:

因为我已经用 RezaNoei 的第一个建议完成了它,我无法标记你的答案,尽管你的答案至少同样有用。我对 websockets 很感兴趣,因为将来我想添加聊天功能。所以谢谢。 :)

以上是关于如何在 C# .net 网页上显示来自另一个线程的弹出窗口?的主要内容,如果未能解决你的问题,请参考以下文章

在 Unity / C# 中,.Net 的 async/await 是不是从字面上开始另一个线程?

如何传递 HttpInputStream 的内容并将其发送到 c# .net 中的另一个 Rest Api

如何使用c#在asp.net网页中显示C程序错误

使用来自另一个表单的数据更新 datagridview (C#)

如何在 ASP.NET 网站上显示来自硬盘驱动器文件夹的图像列表?

从另一个类中的另一个线程创建和显示 WindowsForm - C# [关闭]