【问题标题】:asp.net: javascript function works when called from button click event, not when called from subscription event from redisasp.net:javascript函数在从按钮单击事件调用时起作用,而不是从redis的订阅事件调用时起作用
【发布时间】:2020-06-14 20:36:13
【问题描述】:

我在两种情况下都使用相同的 js 脚本调用...一个是从 button_click 事件调用的,它可以正常工作(更改标签文本),如下所示...

public void Test_OnClientClick(object sender, EventArgs e)
        {
            Console.WriteLine("test");
            ClientScript.RegisterStartupScript(this.GetType(), "updateText", "updateText('test');", true);
        }

当从 redis 订阅引发的事件中调用它时,相同的调用不起作用...

public void Page_Load(object sender, EventArgs e)
    {
        // Establish connection
        redisConn = ConnectionMultiplexer.Connect(redisIP);
        rbsub = redisConn.GetSubscriber();
        rbsub.Subscribe(ServerRedisChannel).OnMessage(channelMessage => {
            MessageHandler(channelMessage.Message.ToString());
        });

    }


    public void MessageHandler(string cm)
    {
        try
        {
            //Test_OnClientClick(null, null);
            ClientScript.RegisterStartupScript(this.GetType(), "updateText", "updateText('test');", true);
        }
        catch (Exception e)
        {
            var x = e;
        }
    }

我确认它通过断点到达 MessageHandler 中的 ClientScript 调用,但它从未到达 js 脚本中的调试器。

完整代码如下:

Default.aspx

<%@ Page Title="Home Page" Async="true" Language="C#" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebForm._Default" %>

<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<script type="text/javascript">

    function updateText(strData) {
        debugger;
        document.getElementById("<%=lblTest.ClientID%>").innerHTML = strData;
    }

</script> 

    <div class="jumbotron">
        <h1>redis test</h1>

        <p><asp:Label ID="lblTest" runat="server" Text="redis output"></asp:Label></p>
        <asp:Button ID="Button1" runat="server" Text="Button" OnClick="Test_OnClientClick"/>

        <p><a href="http://www.asp.net" class="btn btn-primary btn-lg">Learn more &raquo;</a></p>
    </div>



</asp:Content>

Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using StackExchange.Redis;


namespace WebForm
{
    public partial class _Default : Page
    {
        ConnectionMultiplexer redisConn;
        ISubscriber rbsub;
        public const string redisIP = "gptdevnj01:6379";
        public const string ServerRedisChannel = "ac"; 
        public const int redisDB = 7;


        public void Page_Load(object sender, EventArgs e)
        {
            // Establish connection
            redisConn = ConnectionMultiplexer.Connect(redisIP);
            rbsub = redisConn.GetSubscriber();
            rbsub.Subscribe(ServerRedisChannel).OnMessage(channelMessage => {
                MessageHandler(channelMessage.Message.ToString());
            });

        }


        public void MessageHandler(string cm)
        {
            try
            {
                //Test_OnClientClick(null, null);
                ClientScript.RegisterStartupScript(this.GetType(), "updateText", "updateText('test');", true);
            }
            catch (Exception e)
            {
                var x = e;
            }
        }
        public void Test_OnClientClick(object sender, EventArgs e)
        {
            Console.WriteLine("test");
            ClientScript.RegisterStartupScript(this.GetType(), "updateText", "updateText('test');", true);
        }


    }
}

所以我想问题归结为从 button_click 事件调用 js 脚本与从订阅(或异步)事件调用时不同?

【问题讨论】:

    标签: javascript c# asp.net redis


    【解决方案1】:

    对按钮点击的响应发生在ASP.NET Page Lifecycle 内,而处理来自 Redis 订阅的异步消息很可能:

    1. 完全在该生命周期之外发生,并且
    2. 在完全不同的线程中。

    除非您以某种方式同步这些线程(一个处理请求,一个处理接收到的消息) - 您对ClientScript.RegisterStartupScript 的调用将变为无效、错误的客户端或只是失败。但请注意,异步操作的性质可能需要您采用不同的方法,而不是阻止线程等待消息。

    【讨论】:

    • 谢谢,是的,这就是我正在研究的路径...如何处理 Redis 订阅事件以允许它更新网页...有什么想法吗?我需要 SignalR 或类似的吗?请记住,按钮仅用于测试,消息处理程序应更新网页
    • 是的,使用 WebSockets 是一种选择,但像往常一样,答案是“视情况而定”。这取决于用户的要求/期望。
    • 这证实了我对继续使用 SignalR 路径的怀疑,因此我将其标记为已回答,谢谢@tomasz
    猜你喜欢
    • 2020-10-25
    • 1970-01-01
    • 1970-01-01
    • 2018-09-18
    • 2014-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-19
    相关资源
    最近更新 更多