【问题标题】:How should I make a custom Trace:Listener for displaying trace info on a web page?我应该如何制作自定义 Trace:Listener 以在网页上显示跟踪信息?
【发布时间】:2013-05-21 16:41:19
【问题描述】:

我有一个 MVC4 应用程序,它有一个或两个长时间运行的请求。为此,首先,迭代我将把这些作为同步任务。但是,我希望将这些任务的跟踪输出显示在我的 Web 应用程序的可选“进度”窗口中。

我看到了两个候选解决方案,涉及一个数据库跟踪侦听器,或者一个对存储在会话中的“跟踪集合”对象拥有权限的跟踪侦听器。然后“进度”窗口可以使用setInterval 和 Ajax 调用定期轮询这些跟踪存储。

这听起来太简单了,这就是为什么我要问我应该怎么做。有没有更好的方法、既定的模式和技术,还是没有什么价值的练习?

【问题讨论】:

    标签: asp.net-mvc asp.net-mvc-4 trace system.diagnostics trace-listener


    【解决方案1】:

    您可以使用 SignalR 将跟踪消息从服务器端直接发送到浏览器中的“进度窗口”。

    Dino Esposito 在 msdn 上写了一个 article,用进度条做了类似的事情。

    这样您就不需要从进度窗口轮询服务器,也不需要在轮询请求之间使用 Session 来存储消息。


    已编辑:添加示例

    自从那篇文章写完之后,SignalR 发生了一些变化。除了在 global.asax 中注册路由并在视图中包含脚本之外,您还需要以下一段 javascript 来初始化客户端 signalR 代理并添加一个函数来显示进度信息:

    <script type="text/javascript">
        $(document).ready(function () {    
    
            // Create a proxy for the server endpoint            
            var progressHub = $.connection.progressHub;
            $.connection.hub.start();
    
            // Add a client-side callback to process any data
            // received from the server
            progressHub.client.addProgress = function (message) {
                $('#progress').append('<li>' + message + '</li>');
            };
    
        });
    </script>
    

    假设您在该页面上有一个按钮可以触发服务器中的长时间运行的进程。为简单起见,我将使用以下 jquery 调用来调用 home 控制器中名为 RunProcess 的方法。它将传递 SignalR 客户端的 id,以便服务器知道谁需要接收进度数据:

    $("#runProcess").click(function () {                
        var id = $.connection.hub.id;
        $.get("/Home/RunProcess/" + id);
    });
    

    在服务器端,HomeController 的以下方法将模拟长时间运行的过程。为了使用 SignalR 通知客户端,您需要使用 GlobalHost.ConnectionManager.GetHubContext&lt;T&gt;() 获取上下文。然后它将需要调用已在客户端代理上定义的方法addProgress(message),但仅针对具有接收到的 Id 的客户端:

    public void RunProcess(string id)
    {
        var progressHub = GlobalHost.ConnectionManager.GetHubContext<ProgressHub>();
    
        progressHub.Clients.Client(id).addProgress("25% completed");
        Thread.Sleep(2000);
    
        progressHub.Clients.Client(id).addProgress("50% completed");
        Thread.Sleep(3000);
    
        progressHub.Clients.Client(id).addProgress("75% completed");
        Thread.Sleep(2000);
    
        progressHub.Clients.Client(id).addProgress("Process Finished");
    }
    

    【讨论】:

    • 所以我会写一个SignalRTraceListener?很有趣。
    • 我已经添加了一些示例代码,使用来自 NuGet 的最新版本的 SignalR(它与文章中使用的有所不同)。然后,您可以将服务器端代码调整为 `SignalRTraceListener。
    猜你喜欢
    • 2014-12-09
    • 1970-01-01
    • 2014-10-24
    • 1970-01-01
    • 2015-07-20
    • 1970-01-01
    • 2013-09-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多