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

如何在C#.net网页上显示来自另一个线程的弹出窗口?,c#,multithreading,user-interface,asp.net-webpages,C#,Multithreading,User Interface,Asp.net Webpages,我有一个带有母版页的asp.net网页。在服务器端,我有和mssql数据库交互的控制台应用程序(定期向数据库插入行)。在web页面代码隐藏中,我使用SqlTableDependency捕捉该操作。问题是:我认为要实现这一点,我需要一个无限循环中的另一个线程来“侦听”并且不阻塞原始UI线程。我以某种方式通过某种弹出窗口通知用户,插入已成功完成,但由于它运行在不同的线程上,因此它根本无法访问页面控件。我尝试了MessageBox和javascript alert,但没有成功。我做了一些研究,但只在w

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

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


  }
}
public分部类ProdData\u Main:System.Web.UI.Page
{
受保护的无效页面加载(对象发送方、事件参数e)
{
如果(!IsPostBack)
{
ThreadStart childref2=新的ThreadStart(NotifySqlChanges);
线程childThread2=新线程(childref2);
childThread2.Start();
}否则{
//一些现在不重要的代码。。。
}
}
public void NotifySqlChanges()
{
string connString=getConnectionString();
var mapper=新的ModelToTableMapper();
AddMapping(c=>c.Value,“Value”);
使用(var dep=new SqlTableDependency(connString,“产品数据业务对象”,映射器,null,null,TableDependency.Enums.DmlTriggerType.Insert,false))
{
dep.OnChanged+=已更改;
副启动();
while(true)
{
//这里是监听动作的无限循环
}
}
//Debug.WriteLine(“终止”);
}    
公共无效已更改(对象发送方,RecordChangedEventArgs e)
{
var changedEntity=e.实体;
//这里将是通知用户的最佳场所
//不知道…(控件如何从System.Web.UI派生,因此无法
//使用Invoke,并且ScriptManager.RegisterStartupscript不工作
}
}

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

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

2) 使用web套接字。检查以下WebSocket的示例实现。


您可以在internet上找到与web套接字相关的文章

在编写
WebApplication
时,与客户端进行实时交互已经是一个问题。因为Http不记得客户端。
因此,您必须使用
signar
Ajax
(更简单)将此功能添加到Web应用程序中

您需要将新更改的数据(来自mssql)存储到静态集合中(如
静态列表
)。(如果您有多个用户,最好让他们进入
会话

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

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


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

你需要了解。请求完成后,您不能向用户发送任何新数据,除非用户通过ajax调用或类似方式请求数据。感谢您的澄清。我对页面生命周期感到困惑。:)很好,我使用ajax实现了它。谢谢。:)因为我是按照雷扎诺的第一个建议来做的,所以我无法标出你的答案,尽管你的答案至少同样有用。我对WebSocket感兴趣,因为将来我想增加聊天功能。所以谢谢你
 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 :)");
     }
 }