Java自学者论坛

 找回密码
 立即注册

手机号码,快捷登录

恭喜Java自学者论坛(https://www.javazxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,会员资料板块,购买链接:点击进入购买VIP会员

JAVA高级面试进阶训练营视频教程

Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程Go语言视频零基础入门到精通Java架构师3期(课件+源码)
Java开发全终端实战租房项目视频教程SpringBoot2.X入门到高级使用教程大数据培训第六期全套视频教程深度学习(CNN RNN GAN)算法原理Java亿级流量电商系统视频教程
互联网架构师视频教程年薪50万Spark2.0从入门到精通年薪50万!人工智能学习路线教程年薪50万大数据入门到精通学习路线年薪50万机器学习入门到精通教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程MySQL入门到精通教程
查看: 716|回复: 0

C#关于软件界面无响应、BUG报警、程序异常退出等情况的监控和报警

[复制链接]
  • TA的每日心情
    奋斗
    2024-4-6 11:05
  • 签到天数: 748 天

    [LV.9]以坛为家II

    2034

    主题

    2092

    帖子

    70万

    积分

    管理员

    Rank: 9Rank: 9Rank: 9

    积分
    705612
    发表于 2021-6-27 00:36:49 | 显示全部楼层 |阅读模式

    对程序的监控,一般采用另外一个进程进行监控(即主进程和监控进程),主进程运行后,先查找下看有没有还在残留运行的监控进程,如果有先结束监控进程,然后重新启动。

    如何监控主程序的思路是:主程序中开辟一个共享内存映射文件,通过定时器向文件写入变化的信号数据(自定义)。监控程序定时从共享内存文件中读取信号数据,并和上次读取的信号数据进行对比,如果不一致表示主程序运行正常,如果不一致,表示运行异常或者程序异常退出。

    内存映射文件

    内存映射文件是由一个文件到进程地址空间的映射。

            C#提供了允许应用程序把文件映射到一个进程的函(MemoryMappedFile.CreateOrOpen)。内存映射文件与虚拟内存有些类似,通过内存映射文件可以保留一个地址空间的区域,同时将物理存储器提交给此区域,只是内存文件映射的物理存储器来自一个已经存在于磁盘上的文件,而非系统的页文件,而且在对该文件进行操作之前必须首先对文件进行映射,就如同将整个文件从磁盘加载到内存。由此可以看出,使用内存映射文件处理存储于磁盘上的文件时,将不必再对文件执行I/O操作,这意味着在对文件进行处理时将不必再为文件申请并分配缓存,所有的文件缓存操作均由系统直接管理,由于取消了将文件数据加载到内存、数据从内存到文件的回写以及释放内存块等步骤,使得内存映射文件在处理大数据量的文件时能起到相当重要的作用。另外,实际工程中的系统往往需要在多个进程之间共享数据,如果数据量小,处理方法是灵活多变的,如果共享数据容量巨大,那么就需要借助于内存映射文件来进行。实际上,内存映射文件正是解决本地多个进程间数据共享的最有效方法。

            共享内存是内存映射文件的一种特殊情况,内存映射的是一块内存,而非磁盘上的文件。共享内存的主语是进程(Process),操作系统默认会给每一个进程分配一个内存空间,每一个进程只允许访问操作系统分配给它的哪一段内存,而不能访问其他进程的。而有时候需要在不同进程之间访问同一段内存,怎么办呢?操作系统给出了创建访问共享内存的API,需要共享内存的进程可以通过这一组定义好的API来访问多个进程之间共有的内存,各个进程访问这一段内存就像访问一个硬盘上的文件一样。而.Net 4.0中引入了System.IO.MemoryMappedFiles命名空间,这个命名空间的类对windows 共享内存相关API做了封装,使.Net程序员可以更方便的使用内存映射文件。

    内存映射文件实现进程间通讯

            内存映射文件是实现进程通讯的又一种方法,我们可以通过共享剪贴板、共享物理文件来实现进程间的数据共享,这里我们还可以通过内存映射文件来实现共享,这样,文件内的数据就可以用内存读/写指令来访问,而不是用ReadFile和WriteFile这样的I/O系统函数,从而提高了文件存取速度。这种方式更加快捷高效,最适用于需要读取文件并且对文件内包含的信息做语法分析的应用程序,如:对输入文件进行语法分析的彩色语法编辑器,编译器等。这种数据共享是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。

    注意:

            对文件映射对象要使用同一名字。

            是让两个或多个进程映射同一文件映射对象的视图,即它们在共享同一物理存储页。这样,当一个进程向内存映射文件的一个视图写入数据时,其他的进程立即在自己的视图中看到变化。但要注意,对文件映射对象要使用同一名字。

    公用类:

     1 /// <summary>
     2     /// 进程间通讯,共享映射文件
     3     /// </summary>
     4     public class MappingHelper
     5     {
     6         long capacity = 1024 * 1024;
     7         public MemoryMappedFile file;
     8 
     9         public MappingHelper()
    10         {
    11         }
    12 
    13         public MappingHelper(string fileName,string mapName)
    14         {
    15             file = MemoryMappedFile.CreateFromFile(fileName,FileMode.OpenOrCreate,mapName,capacity);
    16         }
    17         
    18         /// <summary>
    19         /// 将消息写入共享映射文件
    20         /// </summary>
    21         /// <param name="msg">消息内容</param>
    22         public void WriteString(string msg)
    23         {
    24             using (var stream = file.CreateViewStream())
    25             {
    26                 using (var writer = new BinaryWriter(stream))
    27                 {
    28                     writer.Write(msg);
    29                 }
    30             }
    31         }
    32         /// <summary>
    33         /// 从共享映射文件中读取消息
    34         /// </summary>
    35         /// <returns></returns>
    36         public string ReadString()
    37         {
    38             using (var stream = file.CreateViewStream())
    39             {
    40                 using (var reader = new BinaryReader(stream))
    41                 {
    42                     List<byte> bytes = new List<byte>();
    43                     byte[] temp = new byte[1024];
    44                     while (true)
    45                     {
    46                         int readCount = reader.Read(temp, 0, temp.Length);
    47                         if (readCount == 0)
    48                         {
    49                             break;
    50                         }
    51                         for (int i = 0; i < readCount; i++)
    52                         {
    53                             bytes.Add(temp);
    54                         }
    55                     }
    56                     if (bytes.Count > 0)
    57                     {
    58                         return Encoding.Default.GetString(bytes.ToArray()).Replace("\0", "");
    59                     }
    60                     else
    61                     {
    62                         return null;
    63                     }
    64                 }
    65             }
    66         }
    67     }
    View Code

    主程序:

     //将指定文件映射到内存中,监控进程读取时,要用一样的内存映射名
    _MappingHelper=new MappingHelper("path","内存中的映射名");
    //通过定时器定时写入变化的数据信号
    private void _Timer_Elapsed(object sender, ElapsedEventArgs e)
            {
                _MappingHelper.WriteString(DateTime.Now.ToString("yyyyMMddHHmmss"));
            }
    View Code

    监控程序:

     1 public static void Main(string[] args)
     2         {
     3             try
     4             {
     5                 mhHelper.file = MemoryMappedFile.OpenExisting("主程序创建的内存映射文件名");
     6                 string laststr = "";
     7                 do
     8                 {                    
     9                      //读取被监控进程定时发送的数据
    10                     string tempstr = mhHelper.ReadString();
    11                     if (tempstr == laststr)//表示程序死机或异常退出
    12                     {
    13                         //此处进行异常处理..................
    14                         DisposeMemoryMapFile();
    15                         Process.GetCurrentProcess().Kill();
    16                     }
    17                     else
    18                     {
    19                         laststr = tempstr;
    20                     }
    21 
    22                     Thread.Sleep(2000);
    23                 }
    24                 while (true);
    25             }
    26             catch (Exception e)
    27             {
    28                 
    29             }
    30         }                        
    View Code

     

    哎...今天够累的,签到来了1...
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|小黑屋|Java自学者论坛 ( 声明:本站文章及资料整理自互联网,用于Java自学者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-21 04:34 , Processed in 0.086855 second(s), 29 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表