wpf 后台如何设置table看不见_(五)如何用WPF Host一个基于SignalR的分布式日志监控工具...

be2dddc48fec34ade56d567fdfff1d8b.png

前面介绍了几篇如何将http://Asp.Net Core、WPF、Unity客户端中的Debug日志记录通过SignalR发送到远程日志监控端的分享。大家可能也看出来了,NebuLog并不是一个完善规划、有清晰产品思路的项目,而是一个出于技术探索的蜻蜓点水式的即兴项目,旨在通过在微软各种技术中实现NebuLog的过程来学习相关技术的结构、运行流程。

那么很自然地我就想到用WPF客户端来做监控工具是怎样一种体验。前面见过,因为我对Html5+JavaScript的了解非常有限,因此在web客户端中存在性能问题。而WPF我相对更熟悉一些,更重要的是,我也想比较一下,现在编译式的Javascript在浏览器中运行的速度能否与基于XAML的接近于原生客户端的速度相媲美?

我觉得桌面应用程序还是存在一些市场的,比如我们熟悉的工具Fiddler、Postman、SourceTree等,尽管普遍认为现在HTML将来一统天下的可能性非常大,甚至有人认为微软已经放弃了XMAL。从WPF向.NET Core和.Net 5靠拢的速度来看,也确实有这种可能,但是至少WPF目前已经支持了.Net Core,并且对.NET 5的支持也在微软规划的路线中,因此可能还有一些盼头。

思路

NebuLogWpfServerSample项目直接包含在NebuLogServerSamples解决方案中,用以代替MVC版本的监控服务端程序。同样,我还是选择了基于.Net Core框架的WPF来生成一个WPF客户端程序。而基于SignalR的NebuLogHub,并不需要另外启动一个iis网站来提供服务,而是直接让WPF来做Hub的宿主。

如果按照我所知道的做法,一般可以用web服务、self-host等方法来为SignalR提供宿主,以前我用WCF时也曾经使用Windows Service方式,应该也适用于SignalR。不过,经过查阅资料,发现可以用WPF来宿主一个WebHost,然后在其中配置SignalR的方式。这与http://Asp.net Core网站项目的结构很像,因此决定采用这种模式。

WPF为http://ASP.NET Core和SignalR提供宿主服务

为了让WPF提供Web服务,我参考了StackOverflow上的一篇博文:

WPF SignalR Server​stackoverflow.com
d3352d9d9c871e9ffa07982179a2a78f.png

这篇文章提供了一种WPF种宿主IHost,基于http://asp.net core 3.1框架的,也就包含了SignalR服务。代码如下:

public partial class App : Application
{
        private IServiceProvider serviceProvider;
       private IHost _host;

        public App()
        {
            IServiceCollection services = new ServiceCollection();

            if (_host!=null) _host.Dispose();
            _host = Host.CreateDefaultBuilder()
                .ConfigureWebHostDefaults(webBuilder => webBuilder
                    .UseUrls("http://*:5999")
                    .ConfigureServices(services =>
                    {
                        services.AddSignalR().AddMessagePackProtocol();
                        services.AddSingleton<MainWindow>();
                    })
                    .Configure(app =>
                    {
                        app.UseRouting();
                        app.UseEndpoints(endpoints => endpoints.MapHub<NebuLogHub>("/NebuLogHub"));
                    }))
               .Build();

            _host.Start();
         }
}

是不是有点眼熟的样子。

而ConfigureServices和Confugure方法都简化了,实际上只要配置NebuLogHub的路由信息即可(如果服务端本身不需要向外发送日志信息)。

然后,把App.xaml中的标签改掉:

<......
    Startup="OnStartup"
    Exit="OnExit">

这样,App执行完构造函数后,就会运行OnStartup回调,这里就可以向DI框架去请求MainWindow的实例并启动窗体了。

protected void OnStartup(object sender, StartupEventArgs e)
        {
            var mainWindow = _host.Services.GetRequiredService<MainWindow>();
            mainWindow.Show();
        }

MainWindow - 监控界面视图

MainWindow被启动的时候,实际上IHost服务已经在运行,NebuLogHub已经在监听状态。我们需要做的是把NebuLogHub收到消息后触发的几个事件注册一下回调响应,然后可以在回调中提供相应的视图刷新动作即可。

public MainWindow(IServiceProvider services, ILoggerFactory factory) : base()
        {
            NebuLogHub.OnILoggingMessageReceived += OnLoggingMessageReceived;
            NebuLogHub.OnAddStatRequestReceived += OnAddStatRequestReceived;
            NebuLogHub.OnRefreshStatRequestReceived += OnRefreshStatRequestRecieved;

            InitializeComponent();
        }

由于我打开WPF的XAML界面时立即感受到一种强烈的冲击:卧槽,XAML这么复杂,几年前攒下的一点点知识已经忘。。。光。。。光。。。勒!

于是我当即决定,实现接收Log消息后立马撤退。

测试

我们还是用NebuLogMvcSample作为测试的客户端来发送日志。

0f05eb2e8a78e31f3d97d9e26ba4ffd3.png

为了实现刷刷刷的感觉还是牺牲了一些视频性能(用DataGrid.ScrollTo在每次收到消息后都去刷新以达到滚动效果),但是数据达到3000条后基本还是能跑。相比之下,http://Asp.Net Core MVC的示例中数据到了1000多条基本就装死了,不过页面中基于Bootstrap Table的表格进行了滚动、按时间排序等重度任务,所以WPF和浏览器的性能也难以从这两个简单的项目来进行性能比较。

不过WPF毕竟还是原生的桌面应用,通过后台C#可以对数据进行各种灵活的处理,可能这也是WPF存在的理由之一吧。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值