Winform Global exception and task parallel library exception;

static class Program
    {
        /// 
        /// 应用程序的主入口点。
        /// 
        [STAThread]
        static void Main()
        {
            try
            {

                //添加事件处理程序未捕获的异常   
                Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
                //添加事件处理UI线程异常   
                Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
                //添加事件处理非UI线程异常   
                AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);


                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new FrmActivity());
            }
            catch (Exception ex)
            {
                string str = "";
                string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";

                if (ex != null)
                {
                    str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
                         ex.GetType().Name, ex.Message, ex.StackTrace);
                }
                else
                {
                    str = string.Format("应用程序线程错误:{0}", ex);
                }

                //写日志
                WriteLog.WriteErrLog(str);
                MessageBox.Show("发生致命错误,请及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

        }

        /// 
        ///这就是我们要在发生未处理异常时处理的方法,做法很多,可以是把出错详细信息记录到文本、数据库,发送出错邮件到作者信箱或出错后重新初始化等等
        /// 
        /// 
        /// 
        static void Application_ThreadException(object sender, System.Threading.ThreadExceptionEventArgs e)
        {

            string str = "";
            string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
            Exception error = e.Exception as Exception;
            if (error != null)
            {
                str = string.Format(strDateInfo + "异常类型:{0}\r\n异常消息:{1}\r\n异常信息:{2}\r\n",
                     error.GetType().Name, error.Message, error.StackTrace);
            }
            else
            {
                str = string.Format("应用程序线程错误:{0}", e);
            }
            //写日志
            WriteLog.WriteErrLog(str);
            MessageBox.Show("发生致命错误,请及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }
        /// 
        ///  ' 处理UI异常
        /// 
        /// 
        /// 
        static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            string str = "";
            Exception error = e.ExceptionObject as Exception;
            string strDateInfo = "出现应用程序未处理的异常:" + DateTime.Now.ToString() + "\r\n";
            if (error != null)
            {
                str = string.Format(strDateInfo + "Application UnhandledException:{0};\n\r堆栈信息:{1}", error.Message, error.StackTrace);
            }
            else
            {
                str = string.Format("Application UnhandledError:{0}", e);
            }
            //写日志
            WriteLog.WriteErrLog(str);
            MessageBox.Show("发生致命错误,请停止当前操作并及时联系作者!", "系统错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
        }

    }
View Code

 

The above code can capture exception that are generated by new Thread(()=>{throw new Exception();}).Start(); 

but cannot capture Task exception; For tasks, refer to below and see relevant;

Ps:

Exception handling in Task parallel library:

while(!task1.IsCompleted){}// Or Task.Wait(); and catch the exception in UI thread;

if(task.status==TaskStatus.falted){

foreach(var e in task1.Exception.InnerException){

//Log the exception

}

}

async button event handler method triggers task exception to UI thread;

https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/exception-handling-task-parallel-library 

 Make use of SynchronizationContext in synchronous methods to operate UI thread:

var ctx = SynchronizationContext.Current;

            new Thread(() => {
                Thread.Sleep(3000);
                ctx.Post(d => {
                    this.panel2.Controls.Add(new Button { Text = "aa", Width = 15, Height = 15 });

                }, null);



            }).Start();

  

How to debug a parallel application:

https://docs.microsoft.com/en-us/visualstudio/debugger/walkthrough-debugging-a-parallel-application?view=vs-2019#c-sample

 

Flexible use of empty condition block {} to isolate code is a good way to avoid hard naming case; like { a=0; return 1;} {a=0; return 2;}, this code is valid but name a can be used in both scopes.

 

[InvocationList]https://blog.csdn.net/zxkid/article/details/1444396

 public static Delegate[] GetComponentEventDelegate(Component component, string EventName, string EventHandlerTypeName)
        {
            Type componentType = component.GetType();
            PropertyInfo eventsPropertyInfo = componentType.GetProperty("Events", BindingFlags.Instance | BindingFlags.NonPublic);
            EventHandlerList eventHanlderList = eventsPropertyInfo.GetValue(component, null) as EventHandlerList;
            FieldInfo HeadFieldInfo = eventHanlderList.GetType().GetField("head", BindingFlags.Instance | BindingFlags.NonPublic);
            object HeadObject = HeadFieldInfo.GetValue(eventHanlderList);

            do
            {
                FieldInfo[] fieldInfoList = componentType.GetFields(BindingFlags.Static | BindingFlags.Instance | BindingFlags.NonPublic);
                foreach (FieldInfo fieldInfo in fieldInfoList)
                {
                    object fieldValue = fieldInfo.GetValue(component);
                    if (fieldValue != null)
                    {
                        Type fieldType = fieldValue.GetType();
                        if (fieldType.Name == EventHandlerTypeName && (fieldValue as Delegate) != null)
                        {
                            return (fieldValue as Delegate).GetInvocationList();
                        }
                        else if (fieldType.Name == typeof(Object).Name)
                        {
                            if (fieldInfo.Name.IndexOf(EventName, StringComparison.OrdinalIgnoreCase) > -1)
                            {
                                if (HeadObject != null)
                                {
                                    Delegate delegateObject = eventHanlderList[fieldValue];
                                    if (delegateObject != null)
                                        return delegateObject.GetInvocationList();
                                }
                            }
                        }
                    }
                }
                componentType = componentType.BaseType;
            } while (componentType != null);

            if (HeadObject != null)
            {
                object ListEntry = HeadObject;
                Type ListEntryType = ListEntry.GetType();
                FieldInfo handlerFieldInfo = ListEntryType.GetField("handler", BindingFlags.Instance | BindingFlags.NonPublic);
                FieldInfo keyFieldInfo = ListEntryType.GetField("key", BindingFlags.Instance | BindingFlags.NonPublic);
                FieldInfo nextFieldInfo = ListEntryType.GetField("next", BindingFlags.Instance | BindingFlags.NonPublic);

                while (ListEntry != null)
                {
                    Delegate handler = handlerFieldInfo.GetValue(ListEntry) as Delegate;
                    object key = keyFieldInfo.GetValue(ListEntry);
                    ListEntry = nextFieldInfo.GetValue(ListEntry);

                    if (handler != null && handler.GetType().Name == EventHandlerTypeName)
                        return handler.GetInvocationList();
                }
            }
            return null;
        }
View Code

 [Editor](https://github.com/jacobslusser/ScintillaNET)

Threadpool play method thought of by experiment by me?:

 public volatile static int flag = 0;

        public static JObject config = new JObject();
        static ManualResetEvent _event = new ManualResetEvent(false);
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main()
        {
            List threads = new List();

            Action action = () =>
            {
            };
            Thread th = new Thread(() =>
            {
                while (flag != 1)
                {
                    action();
                    //Monitor.Enter(config);
                    //Thread.CurrentThread.Suspend();
                    _event.WaitOne();
                }
            })
            { IsBackground = true };
            th.Start();
            threads.Add(th);
            Thread.Sleep(500);
            var state = threads[0].ThreadState;
            var isRunning = threads[0].IsAlive;
            //start the thread again
            action = () =>
            {

            };
            _event.Reset();
            _event.Set();
            //threads[0].Resume();
            //Monitor.Exit(config);

            Semaphore s = new Semaphore(2, 4);
View Code

 Semaphore reprinted:

Semaphore:可理解为允许线程执行信号的池子,池子中放入多少个信号就允许多少线程同时执行。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
    
private static void MultiThreadSynergicWithSemaphore()
  {
   //0表示创建Semaphore时,拥有可用信号量数值
   //1表示Semaphore中,最多容纳信号量数值
   Semaphore semaphore = new Semaphore(0, 1);
 
 
   Thread thread1 = new Thread(() =>
   {
    //线程首先WaitOne等待一个可用的信号量
    semaphore.WaitOne();
    //在得到信号量后,执行下面代码内容
    Console.WriteLine("thread1 work");
    Thread.Sleep(5000);
    //线程执行完毕,将获得信号量释放(还给semaphore)
    semaphore.Release();
   });
 
 
   Thread thread2 = new Thread(() =>
   {
    semaphore.WaitOne();
    Console.WriteLine("thread2 work");
    Thread.Sleep(5000);
    semaphore.Release();
   });
   thread2.Start();
   thread1.Start();
   //因在创建Semaphore时拥有的信号量为0
   //semaphore.Release(1) 为加入1个信号量到semaphore中
   semaphore.Release(1);
  }

说明:

1、如果semaphore.Release(n),n>semaphore最大容纳信号量,将出异常。
2、当semaphore拥有的信号量为1时,Semaphore相当于Mutex
3、当semaphore拥有的信号量>1时,信号量的数量即可供多个线程同时获取的个数,此时可认为获取到信号量的线程将同时执行(实际情况可能与CPU核心数、CPU同时支出线程数有关)
View Code

 Multidownload reprinted:

public class MultiDownload
  {
   #region 变量
   private int _threadNum;    //线程数量
   private long _fileSize;    //文件大小
   private string _fileUrl;   //文件地址
   private string _fileName;   //文件名
   private string _savePath;   //保存路径
   private short _threadCompleteNum; //线程完成数量
   private bool _isComplete;   //是否完成
   private volatile int _downloadSize; //当前下载大小(实时的)
   private Thread[] _thread;   //线程数组
   private List<string> _tempFiles = new List<string>();
   private object locker = new object();
   #endregion
   #region 属性
   /// 
   /// 文件名
   /// 
   public string FileName
   {
    get
    {
     return _fileName;
    }
    set
    {
     _fileName = value;
    }
   }
   /// 
   /// 文件大小
   /// 
   public long FileSize
   {
    get
    {
     return _fileSize;
    }
   }
   /// 
   /// 当前下载大小(实时的)
   /// 
   public int DownloadSize
   {
    get
    {
     return _downloadSize;
    }
   }
   /// 
   /// 是否完成
   /// 
   public bool IsComplete
   {
    get
    {
     return _isComplete;
    }
   }
   /// 
   /// 线程数量
   /// 
   public int ThreadNum
   {
    get
    {
     return _threadNum;
    }
   }
   /// 
   /// 保存路径
   /// 
   public string SavePath
   {
    get
    {
     return _savePath;
    }
    set
    {
     _savePath = value;
    }
   }
   #endregion
   /// 
   /// 构造函数
   /// 
   /// 线程数量
   /// 文件Url路径
   /// 本地保存路径
   public MultiDownload(int threahNum, string fileUrl, string savePath)
   {
    this._threadNum = threahNum;
    this._thread = new Thread[threahNum];
    this._fileUrl = fileUrl;
    this._savePath = savePath;
   }
   public void Start()
   {
    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(_fileUrl);
    HttpWebResponse response = (HttpWebResponse)request.GetResponse();
    _fileSize = response.ContentLength;
    int singelNum = (int)(_fileSize / _threadNum);  //平均分配
    int remainder = (int)(_fileSize % _threadNum);  //获取剩余的
    request.Abort();
    response.Close();
    for (int i = 0; i < _threadNum; i++)
    {
     List<int> range = new List<int>();
     range.Add(i * singelNum);
     if (remainder != 0 && (_threadNum - 1) == i) //剩余的交给最后一个线程
      range.Add(i * singelNum + singelNum + remainder - 1);
     else
      range.Add(i * singelNum + singelNum - 1);
     //下载指定位置的数据
     int[] ran = new int[] { range[0], range[1] };
     _thread[i] = new Thread(new ParameterizedThreadStart(Download));
     _thread[i].Name = System.IO.Path.GetFileNameWithoutExtension(_fileUrl) + "_{0}".Replace("{0}", Convert.ToString(i + 1));
     _thread[i].Start(ran);
    }
    //MessageBox.Show("下载完成!");
   }
   private void Download(object obj)
   {
    Stream httpFileStream = null, localFileStram = null;
    try
    {
     int[] ran = obj as int[];
     string tmpFileBlock = System.IO.Path.GetTempPath() + Thread.CurrentThread.Name + ".tmp";
     _tempFiles.Add(tmpFileBlock);
     HttpWebRequest httprequest = (HttpWebRequest)WebRequest.Create(_fileUrl);
     httprequest.AddRange(ran[0], ran[1]);
     HttpWebResponse httpresponse = (HttpWebResponse)httprequest.GetResponse();
     httpFileStream = httpresponse.GetResponseStream();
     localFileStram = new FileStream(tmpFileBlock, FileMode.Create);
     byte[] by = new byte[5000];
     int getByteSize = httpFileStream.Read(by, 0, (int)by.Length); //Read方法将返回读入by变量中的总字节数
     while (getByteSize > 0)
     {
      Thread.Sleep(20);
      lock (locker) _downloadSize += getByteSize;
      localFileStram.Write(by, 0, getByteSize);
      getByteSize = httpFileStream.Read(by, 0, (int)by.Length);
     }
     lock (locker) _threadCompleteNum++;
    }
    catch (Exception ex)
    {
     throw new Exception(ex.Message.ToString());
    }
    finally
    {
     if (httpFileStream != null) httpFileStream.Dispose();
     if (localFileStram != null) localFileStram.Dispose();
    }
    if (_threadCompleteNum == _threadNum)
    {
     Complete();
     _isComplete = true;
    }
   }
   /// 
   /// 下载完成后合并文件块
   /// 
   private void Complete()
   {
    Stream mergeFile = null;
    BinaryWriter AddWriter = null;
    try
    {
     using (mergeFile = new FileStream(@_savePath, FileMode.Create)) //根据实际情况调整FileMode
     {
      AddWriter = new BinaryWriter(mergeFile);
      foreach (string file in _tempFiles)
      {
       using (FileStream fs = new FileStream(file, FileMode.Open))
       {
        BinaryReader TempReader = new BinaryReader(fs);
        AddWriter.Write(TempReader.ReadBytes((int)fs.Length));
        TempReader.Close();
       }
       File.Delete(file);
      }
     }
     MyMessageBox.Show("下载完成!");
    }
    catch (Exception ex)
    {
     throw new Exception(ex.Message);
    }
    finally
    {
     if (AddWriter != null)
     {
      AddWriter.Close();
      AddWriter.Dispose();
     }
     if (mergeFile != null)
     {
      mergeFile.Close();
      mergeFile.Dispose();
     }
    }
   }
  }
View Code

 Mutex reprinted:

            #region 只能运行一个程序
            bool flag = false;
            Mutex mutex = new Mutex(true, "Test", out flag);
            //第一个参数:true--给调用线程赋予互斥体的初始所属权
            //第一个参数:互斥体的名称
            //第三个参数:返回值,如果调用线程已被授予互斥体的初始所属权,则返回true
            if (!flag)
            {
                MessageBox.Show("程序已运行!", "确定", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                Environment.Exit(1);//退出程序
            }
            #endregion
        }
View Code

 Volatile reprinted:

恐怕比较一下volatile和synchronized的不同是最容易解释清楚的。volatile是变量修饰符,而synchronized则作用于一段代码或方法;看如下三句get代码:

    int i1;              int geti1() {return i1;}
    volatile int i2;  int geti2() {return i2;}
    int i3;              synchronized int geti3() {return i3;} 

  geti1()得到存储在当前线程中i1的数值。多个线程有多个i1变量拷贝,而且这些i1之间可以互不相同。换句话说,另一个线程可能已经改变了它线程内的i1值,而这个值可以和当前线程中的i1值不相同。事实上,Java有个思想叫“主”内存区域,这里存放了变量目前的“准确值”。每个线程可以有它自己的变量拷贝,而这个变量拷贝值可以和“主”内存区域里存放的不同。因此实际上存在一种可能:“主”内存区域里的i1值是1,线程1里的i1值是2,线程2里的i1值是3——这在线程1和线程2都改变了它们各自的i1值,而且这个改变还没来得及传递给“主”内存区域或其他线程时就会发生。
  而geti2()得到的是“主”内存区域的i2数值。用volatile修饰后的变量不允许有不同于“主”内存区域的变量拷贝。换句话说,一个变量经volatile修饰后在所有线程中必须是同步的;任何线程中改变了它的值,所有其他线程立即获取到了相同的值。理所当然的,volatile修饰的变量存取时比一般变量消耗的资源要多一点,因为线程有它自己的变量拷贝更为高效。
  既然volatile关键字已经实现了线程间数据同步,又要synchronized干什么呢?呵呵,它们之间有两点不同。首先,synchronized获得并释放监视器——如果两个线程使用了同一个对象锁,监视器能强制保证代码块同时只被一个线程所执行——这是众所周知的事实。但是,synchronized也同步内存:事实上,synchronized在“主”内存区域同步整个线程的内存。因此,执行geti3()方法做了如下几步:
1. 线程请求获得监视this对象的对象锁(假设未被锁,否则线程等待直到锁释放)
2. 线程内存的数据被消除,从“主”内存区域中读入(Java虚拟机能优化此步。。。[后面的不知道怎么表达,汗])
3. 代码块被执行
4. 对于变量的任何改变现在可以安全地写到“主”内存区域中(不过geti3()方法不会改变变量值)
5. 线程释放监视this对象的对象锁
  因此volatile只是在线程内存和“主”内存间同步某个变量的值,而synchronized通过锁定和解锁某个监视器同步所有变量的值。显然synchronized要比volatile消耗更多资源。
View Code

 Exercise:

            private class ThreadPool
            {
                //to be performant
                private int maxSize = 5;
                private List threads = new List();
                private volatile Action _runable;


                private void StartNew(Action action)
                {
                    this._runable = action;
                    if (threads.Count < maxSize)
                    {
                        var t = new Thread(() => { while (true) { _runable(); Thread.CurrentThread.Suspend(); } });
                        t.Start();
                        threads.Add(t);
                    }
                    else
                    {
                        //exceed equal maxSize
                        var t = threads.First(a => a.IsAlive && a.ThreadState != System.Threading.ThreadState.Running);
                        t.Resume();
                    }

                }
            }

            private class ConnectionPool : IDisposable
            {
                private List pool = new List();
                private int maxSize = 5;
                private DbConnection GetOpenConnection()
                {
                    if (pool.Count < maxSize)
                    {
                        var conn = new SqlConnection();
                        pool.Add(conn);
                        return conn;
                    }
                    else
                    {
                        //==maxSize
                        return pool.First(c => c.State != System.Data.ConnectionState.Open);
                    }
                }

                private bool _disposed = false;
                protected virtual void Dispose(bool disposing)
                {
                    if (_disposed) return;
                    if (disposing)
                    {
                        pool.ForEach(c => c.Dispose());
                    }
                    pool.Clear();
                    _disposed = true;
                }

                public void Dispose()
                {
                    Dispose(true);
                    GC.SuppressFinalize(this);
                }

                ~ConnectionPool()
                {
                    Dispose(false);
                }
            }

            public class Singleton where T : new()
            {
                private Singleton()
                {
                }
                public static T Instance = new T();
            }

            public class Cache : ConcurrentDictionary<string, object>
            {

            }
View Code

 GetGenericTypeDefinition

            Gene<int> asd = new Gene<int>();
            var aa1 = asd.GetType().GetGenericTypeDefinition();
            var asd1 = aa1.Equals(typeof(Gene<>));
View Code

 Practice:

using FontAwesome.Sharp;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace zgraphdemo
{
    public partial class Form2 : Form
    {
        private volatile int num = 5;
        private static ConcurrentDictionary<string, object> instanceCache = new ConcurrentDictionary<string, object>();
        public Form2()
        {
            InitializeComponent();

        }

        private int i = 1;
        private TreeView tree;
        private void button1_Click(object sender, EventArgs e)
        {
            this.panel1.Controls.Clear();
            var btn1 = this.Owner.Controls.Find("button1", true).First() as Button;
            btn1.Text = "returned from dialog";
            var tp = typeof(Case1);
            var ctl = Activator.CreateInstance(tp) as UserControl;
            (ctl.Controls.Find("textbox1", false).First() as TextBox).Text = (i++).ToString();
            ctl.Dock = DockStyle.Fill;
            this.pnCase.Controls.Clear();
            this.pnCase.Controls.Add(ctl);

            tree = new TreeView();
            tree.ImageList = new ImageList();
            tree.ImageList.Images.Add("id", IconChar.IdCard.ToBitmap(32, Color.DeepPink));
            tree.ImageList.Images.Add("state", IconChar.Box.ToBitmap(32, Color.Black));
            tree.CheckBoxes = true;
            tree.Dock = DockStyle.Fill;
            tree.Nodes.Add(new TreeNode { Text = "ancestor", Tag = new { text = "ancestor", id = 0, pid = 0 } });
            //tree.Nodes[0].Nodes.Add("child");
            //tree.Nodes[0].Nodes[0].Nodes.Add("grandchild");
            this.panel1.Controls.Add(tree);
            //this.Close();
            if (tree != null)
            {
                tree.AfterSelect += Tree_AfterSelect;
                tree.AfterCheck += Tree_AfterCheck;
            }

        }
        class Point
        {
            public int x;
            public int y;
        }

        private void button2_Click(object sender, EventArgs e)
        {
            Program.flag = 1;
            if (tree == null) return;
            //tree.Nodes[0].ImageKey = "state";
            //tree.Nodes[0].Tag = 0;
            var nodes = new List<dynamic>() {
                new {text="1",id=1,pid=0 },
                new {text="12",id=2,pid=1 },
                new {text="13",id=3,pid=1 },
                new {text="2",id=4,pid=0 },
                new {text="12",id=5,pid=4 },
                new {text="13",id=6,pid=4 },

            };
            addNode(tree.Nodes[0], nodes);

            tree.Refresh();

            var x = new Point();

            unsafe
            {
                int i = 5;
                int* p = &i;
                fixed (int* p1 = &x.x)
                {
                    *p1 = 22;
                    int p2 = *p1 * 52;
                    int[][][][][][] sdfsdf = null;



                }
            }


        }

        private void GatherNodes(TreeNode jiaobaba, List nodes)
        {
            if (jiaobaba.Nodes.Count > 0)
            {
                nodes.AddRange(jiaobaba.Nodes.Cast());
                foreach (TreeNode item in jiaobaba.Nodes)
                {
                    GatherNodes(item, nodes);

                }
            }
        }

        private void Tree_AfterCheck(object sender, TreeViewEventArgs e)
        {
            var nodes = tree.Nodes.Cast();
            var ns = new List();
            GatherNodes(tree.Nodes[0], ns);
            MessageBox.Show(ns.Count().ToString());


        }

        private void Tree_AfterSelect(object sender, TreeViewEventArgs e)
        {

            if (!instanceCache.ContainsKey(e.Node.Text))
            {

                instanceCache.TryAdd($"select_{e.Node.Text}", new object());
            }
            var instance = instanceCache[$"select_{e.Node.Text}"];
            instance.ToString();
            MessageBox.Show(tree.Nodes.Cast().First().Text);
        }

        private void addNode(TreeNode node, List<dynamic> nodes)
        {

            var children = nodes.Where(c => c.pid == (int)((node.Tag as dynamic).id)).ToArray();
            if (children.Length > 0)
            {
                var childrenN = children.Select(c => new TreeNode { Text = c.text, Tag = c }).ToArray();
                node.Nodes.AddRange(childrenN);
                foreach (var item in childrenN)
                {
                    addNode(item, nodes);
                }
            }
        }
    }
}
View Code
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ZedGraph;
using FontAwesome.Sharp;
using System.Runtime.InteropServices;

namespace zgraphdemo
{
    public partial class Form1 : Form
    {
        private int progressCounter = 1;

        [System.Runtime.InteropServices.DllImport("user32.dll", CharSet = CharSet.Auto)]
        extern static bool DestroyIcon(IntPtr handle);

        public Form1()
        {
            InitializeComponent();
            //this = new FontAwesome.Sharp.Icon(IconChar.Folder);
            this.pictureBox2.Image= IconChar.BatteryEmpty.ToBitmap(32, Color.Blue);
            this.button1.Image = IconChar.Igloo.ToBitmap(32, Color.DeepPink);
            this.button2.Image = IconChar.IdCard.ToBitmap(32, Color.DeepPink);
            var img = IconChar.Cube.ToBitmap(32, Color.DeepPink);
            var hdl = img.GetHicon();
            System.Drawing.Icon icon = System.Drawing.Icon.FromHandle(hdl);
            this.Icon = icon;
            //DestroyIcon(icon.Handle);

            var a = 0.000000;
            this.progressBar1.Visible = false;

            this.timeDraw.Tick += new EventHandler(timeDraw_Tick);
            InflateDataGridView();

            cmbDrivetrainType.Enabled = false;
            var dfxType = new Dictionary<int, string>();
            dfxType.Add(0, "FWD");
            dfxType.Add(1, "RWD");
            dfxType.Add(2, "AWD Permanente");
            dfxType.Add(3, "AWD HangONRA");
            dfxType.Add(4, "AWD HangONFA");
            dfxType.Add(5, "Axlesplit");
            this.cmbDrivetrainType.ValueMember = "Key";
            this.cmbDrivetrainType.DisplayMember = "Value";
            this.cmbDrivetrainType.DataSource = new BindingSource(dfxType, null);
            //for (int i = 0; i < 100; i++)
            //{
            //    this.toolStripProgressBar1.ProgressBar.Step = i;
            //    this.toolStripProgressBar1.ProgressBar.PerformStep();
            //    if (i == 100) this.toolStripProgressBar1.ProgressBar.Step = 0;

            //}
            Interlocked.Increment(ref progressCounter);
            this.toolStripProgressBar1.ProgressBar.Maximum = 5;
            Interlocked.Decrement(ref progressCounter);
            button2.ForeColor = Color.Green;
            button1.BackColor = Color.DarkGoldenrod;
            this.button1.Click += button1_Click;
            this.button3.Click += button3_Click;
            Bitmap bitmap = new Bitmap(300, 300);
            Graphics g = Graphics.FromImage(bitmap);
            g.Clear(Color.Transparent);
            g.DrawLine(new Pen(Color.Blue), 0, 0, 100, 100);
            g.DrawEllipse(Pens.Blue, 0, 0, 10, 30);
            g.DrawString("Caloch", DefaultFont, Brushes.Black, 0, 0);
            g.Save();
            g.Dispose();
            //bitmap.MakeTransparent(Color.Red);

            bitmap.Save("dd.png", ImageFormat.Png);
            pictureBox1.Image = bitmap;
        }


        private void InflateDataGridView()
        {
            DataTable dt = new DataTable();
            dt.Columns.Add("id");
            dt.Columns.Add("text");
            dt.Columns.Add("Delete");
            var row = dt.NewRow();
            row["id"] = 1;
            row["text"] = "text";
            row["Delete"] = "Delete";
            dt.Rows.Add(row);

            this.dataGridView1.DataSource = dt;
        }


        // 起始时间以毫秒为单位
        int tickStart = 0;


        private void Form1_Load(object sender, EventArgs e)
        {
            //获取引用
            GraphPane myPane = zedGraphControl1.GraphPane;

            FormatGraphPane(myPane);
            FormatXAxis(myPane.XAxis);
            FormatYAxis(myPane.YAxis);
            //设置标题
            myPane.Title.Text = "实时曲线";
            //设置X轴说明文字
            myPane.XAxis.Title.Text = "时间";
            //设置Y轴说明文字
            myPane.YAxis.Title.Text = "温度";

            //设置1200个点,假设每50毫秒更新一次,刚好检测1分钟,一旦构造后将不能更改这个值
            RollingPointPairList list = new RollingPointPairList(1200);

            //开始,增加的线是没有数据点的(也就是list为空)
            //增加一条名称:Voltage,颜色Color.Bule,无符号,无数据的空线条
            LineItem curve = myPane.AddCurve("温度", list, Color.Blue, SymbolType.None);

            myPane.AxisChangeEvent += MyPane_AxisChangeEvent;

            timeDraw.Interval = 1000; //设置timer控件的间隔为50毫秒
            timeDraw.Enabled = true; //timer可用
            timeDraw.Start(); //开始

            myPane.XAxis.Scale.Min = 0; //X轴最小值0
            myPane.XAxis.Scale.Max = 30; //X轴最大30
            myPane.XAxis.Scale.MinorStep = 1;//X轴小步长1,也就是小间隔
            myPane.XAxis.Scale.MajorStep = 5;//X轴大步长为5,也就是显示文字的大间隔

            //改变轴的刻度
            zedGraphControl1.AxisChange();

            //保存开始时间
            tickStart = Environment.TickCount;
        }

        private void MyPane_AxisChangeEvent(GraphPane pane)
        {
            pane.XAxis.Color = Color.Green;
        }

        public GraphPane FormatGraphPane(GraphPane gp)
        {
            gp.Border.IsVisible = false;
            gp.Title.IsVisible = false;
            gp.IsFontsScaled = false;

            gp.Margin.All = 1;

            gp.Legend.IsVisible = true;
            gp.Legend.FontSpec.Size = 11;
            gp.Legend.FontSpec.FontColor = Color.Black;
            gp.Legend.Fill = new Fill(Color.FromArgb(255, 255, 255, 255), Color.FromArgb(255, 255, 255, 255));
            gp.Legend.Border.IsVisible = false;

            gp.Chart.Border.Color = Color.LightGray;
            gp.Fill = new Fill(Color.White, Color.White, 0F);
            gp.Chart.Fill = new Fill(Color.White, Color.White, 0);

            if (gp.XAxis != null) FormatXAxis(gp.XAxis);
            if (gp.YAxis != null) FormatYAxis(gp.YAxis);

            return gp;
        }

        public XAxis FormatXAxis(XAxis xAxis)
        {
            xAxis.Title.IsVisible = false;
            xAxis.Title.FontSpec.Size = 11;
            xAxis.Scale.FontSpec.Size = 11;
            xAxis.MajorTic.Color = Color.Gray;
            xAxis.MinorTic.Color = Color.LightGray;
            xAxis.Scale.FontSpec.FontColor = Color.Gray;
            xAxis.Title.FontSpec.FontColor = Color.Gray;
            return xAxis;
        }

        public YAxis FormatYAxis(YAxis yAxis)
        {
            yAxis.Title.IsVisible = true;
            yAxis.Title.FontSpec.Size = 11;
            yAxis.Scale.FontSpec.Size = 11;
            yAxis.Color = Color.LightGray;
            yAxis.MajorTic.Color = Color.Gray;
            yAxis.MinorTic.Color = Color.LightGray;
            yAxis.Scale.FontSpec.FontColor = Color.Gray;
            yAxis.Title.FontSpec.FontColor = Color.Gray;
            return yAxis;
        }


        private void timeDraw_Tick(object sender, EventArgs e)
        {
            //确保CurveList不为空
            if (zedGraphControl1.GraphPane.CurveList.Count <= 0)
            {
                return;
            }

            //取Graph第一个曲线,也就是第一步:在GraphPane.CurveList集合中查找CurveItem
            LineItem curve = zedGraphControl1.GraphPane.CurveList[0] as LineItem;
            if (curve == null)
            {
                return;
            }

            //第二步:在CurveItem中访问PointPairList(或者其它的IPointList),根据自己的需要增加新数据或修改已存在的数据
            IPointListEdit list = curve.Points as IPointListEdit;

            if (list == null)
            {
                return;
            }

            // 时间用秒表示
            double time = (Environment.TickCount - tickStart) / 1000.0;
            // 3秒循环
            list.Add(time, Math.Sin(2.0 * Math.PI * time / 3.0));
            Console.WriteLine(time.ToString());

            Scale xScale = zedGraphControl1.GraphPane.XAxis.Scale;
            if (time > xScale.Max - xScale.MajorStep)
            {
                xScale.Max = time + xScale.MajorStep;
                xScale.Min = xScale.Max - 30.0;
            }

            //第三步:调用ZedGraphControl.AxisChange()方法更新X和Y轴的范围
            zedGraphControl1.AxisChange();

            //第四步:调用Form.Invalidate()方法更新图表
            zedGraphControl1.Invalidate();
        }

        private void Form1_Resize(object sender, EventArgs e)
        {
            SetSize();
        }

        private void SetSize()
        {
            // 控制始终是以10像素插入矩形从客户端的形
            Rectangle formRect = this.ClientRectangle;
            formRect.Inflate(-10, -10);

            if (zedGraphControl1.Size != formRect.Size)
            {
                zedGraphControl1.Location = formRect.Location;
                zedGraphControl1.Size = formRect.Size;
            }
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Cursor = System.Windows.Forms.Cursors.Default;
            DisableControls(this, true);
            var f2 = new Form2();
            f2.ShowDialog(this);
        }

        private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1) return;
            if (dataGridView1.Columns[e.ColumnIndex].Name == "Delete" && dataGridView1.Rows.Count > 1 && e.RowIndex != dataGridView1.Rows.Count - 1)
            {
                dataGridView1.Rows.RemoveAt(e.RowIndex);
            }
        }

        void DisableControls(Control ctl, bool enable)
        {
            ctl.Enabled = enable;
            foreach (Control sub in ctl.Controls)
            {
                DisableControls(sub, enable);
            }
        }


        private async void button2_Click(object sender, EventArgs e)
        {
            SynchronizationContext.Current.Post(a =>
            {


            }, null);



            SynchronizationContext ctx = SynchronizationContext.Current;
            new Thread((x) =>
           {
               var ctx1 = x as SynchronizationContext;

               ctx1.Post(a =>
               {
                   button3_Click(button3, new EventArgs());

                   DisableControls(this.panel1, false);
                   this.Cursor = System.Windows.Forms.Cursors.WaitCursor;
                   this.progressBar1.Visible = true;

               }, null);


               Thread.Sleep(8000);



               ctx1.Post(a =>
               {
                   var dt = dataGridView1.DataSource as DataTable;
                   var row = dt.NewRow();
                   row["id"] = (int)dt.Rows.Count + 1;
                   row["text"] = "text";
                   row["Delete"] = "Delete";
                   dt.Rows.Add(row);

                   button3_Click(button3, new EventArgs());

                   DisableControls(this.panel1, true);
                   this.Cursor = System.Windows.Forms.Cursors.Default;
                   this.progressBar1.Visible = false;
               }, null);
           }).Start(ctx);

            await Task.Factory.StartNew(() =>
            {
                ctx.Post(a =>
                {
                    button3_Click(button3, new EventArgs());
                }, null);
            });
        }

        private void button3_Click(object sender, EventArgs e)
        {
            //RemoveCurves("温度");
            //this.zedGraphControl1.MasterPane.PaneList.Clear();
            //this.zedGraphControl1.MasterPane.Add(new GraphPane());
            //DataTable dt = new DataTable();
            //dt.Columns.Add("id");
            //dt.Columns.Add("text");
            //dt.Columns.Add("Delete");
            //dataGridView1.DataSource = dt;
        }

        public void RemoveCurves(params string[] names)
        {
            names.ToList().ForEach(name =>
            {
                Predicate predicate = c => { return c.Label.Text.ToUpper() == name.ToUpper(); };
                var pane = this.zedGraphControl1.MasterPane.PaneList.Cast().FirstOrDefault(p => p.CurveList.Cast().Any(c => predicate(c)));
                pane?.CurveList.RemoveAt(pane.CurveList.FindIndex(predicate));
            });
            this.zedGraphControl1.Refresh();
            System.Drawing.Rectangle rect = new Rectangle();
            rect.Inflate(40, 40);
        }

        private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                int currentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;
                int currentMouseOverColumn = dataGridView1.HitTest(e.X, e.Y).ColumnIndex;
                ContextMenu m = new ContextMenu();
                var m1 = new MenuItem("Cut");
                m1.Click += (a, b) =>
                {
                    if (currentMouseOverColumn == -1) return;
                    MessageBox.Show(((MenuItem)a).Text + currentMouseOverRow + currentMouseOverColumn + dataGridView1.Columns[currentMouseOverColumn].Name);
                };
                m.MenuItems.Add(m1);
                m.MenuItems.Add(new MenuItem("Copy"));
                m.MenuItems.Add(new MenuItem("Paste"));


                if (currentMouseOverRow >= 0)
                {
                    m.MenuItems.Add(new MenuItem(string.Format("Do something to row {0}", currentMouseOverRow.ToString())));
                }

                m.Show(dataGridView1, new Point(e.X, e.Y));


            }
        }

        private void button3_Click_1(object sender, EventArgs e)
        {
            this.pictureBox2.Image = IconChar.Circle.ToBitmap(32, Color.DarkGreen);
            MessageBox.Show(Program.config["a"]?.ToString());
        }

        private void button4_Click(object sender, EventArgs e)
        {
            this.pictureBox2.Image = IconChar.Circle.ToBitmap(32, Color.Red);
            var p = new Process();
            p.StartInfo.FileName = "notepad.exe";
            p.StartInfo.Arguments = "a.json";
            p.Start();
        }

        private void menuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {

        }

        private void quitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}
View Code
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.Common;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace zgraphdemo
{
    class Gene { }

    static class Program
    {
        //to synchronize value
        public volatile static int flag = 0;

        public static JObject config = new JObject();
        static ManualResetEvent _event = new ManualResetEvent(false);
        /// 
        /// The main entry point for the application.
        /// 
        [STAThread]
        static void Main()
        {
            List threads = new List();

            Action action = () =>
            {
            };
            Thread th = new Thread(() =>
            {
                while (flag != 1)
                {
                    action();
                    //Monitor.Enter(config);
                    //Thread.CurrentThread.Suspend();
                    _event.WaitOne();
                }
            })
            { IsBackground = true };
            th.Start();
            threads.Add(th);
            Thread.Sleep(500);
            var state = threads[0].ThreadState;
            var isRunning = threads[0].IsAlive;
            //start the thread again
            action = () =>
            {

            };
            _event.Reset();
            _event.Set();
            //threads[0].Resume();
            //Monitor.Exit(config);

            Semaphore s = new Semaphore(2, 4);

            Gene<int> asd = new Gene<int>();
            var aa1 = asd.GetType().GetGenericTypeDefinition();
            var asd1 = aa1.Equals(typeof(Gene<>));


            var n = new int[100];
            for (int i = 0; i < 100; i++)
            {
                n[i] = i;
            }

            GetByCreatia requrest1 = new GetByCreatia();
            SendCommandCriteria scc = requrest1.CreateCriteria();
            scc.AndUserIdEqualsTo(55);
            if (scc.Satisfied())
            {

            }
            dynamic service = new { };
            //service?.satisfy(requrest1);
            Mutex m1 = new Mutex();


            try
            {
                config = JObject.Parse(File.ReadAllText("a.json"));
                new Thread(() =>
                {
                    FileSystemWatcher fw = new FileSystemWatcher(".");
                    fw.Filter = "*.json";
                    fw.Changed += (a, aa) =>
                    {
                        System.Threading.Thread.Sleep(500);
                        config = JObject.Parse(File.ReadAllText("a.json"));
                        //MessageBox.Show(config["a"]?.ToString());
                        //File watcher will terminate this thread after changed event is triggered if it will be disposed;

                    };
                    fw.EnableRaisingEvents = true;
                }).Start();


            }
            catch (Exception ex)
            {
                File.WriteAllText("log.txt", ex.Message);
            }
            var b = n as IEnumerable<int>;
            b.Reverse();
            var c = b.Where(n1 => n1 > 10).ToList();
            c.Reverse();
            var d = b.Where(n1 => n1 > 10).ToArray();
            var e = d.Reverse().ToArray();
            TupleElementIsReadonly();

            double a1 = 0;
            var a3 = double.TryParse(null, out a1);
            string[] yAxises = new string[] { "ay", "sas", "VGIF", "vxVeh_VDC", "v_FL", "v_RL", "v_FR", "v_RR", "ThrottlePos", "BlsAsw", "CtlActiveVdc" };
            var y1 = yAxises.Except(new string[] { "ay" });
            var y2 = yAxises.TakeWhile(v => v.StartsWith("a")).ToList();
            var y = yAxises.Skip(yAxises.Length - 2).Take(2).ToArray();
            var y3 = Tuple.Create(2, 3);
            var x = string.Join(",", yAxises.Select(a => $"\"{a}\":\"{a}\""));
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            Application.Run(new Form1());
        }

        private static void TupleElementIsReadonly()
        {
            HashSet<int> n = new HashSet<int>();
            System.Collections.Generic.LinkedList<int> m1 = new LinkedList<int>();
            m1.AddFirst(2);
            m1.AddLast(3);
            SortedList<int, string> n1 = new SortedList<int, string>();
            m1.AddBefore(m1.First, 4);
            n1.Add(2, "3");
            n1.Add(5, "4");
            n1.Add(4, "2");
            n1.Add(3, "1");
            var n2 = n1.Values;
            Debug.Assert(n2[1] == "1");
            Debug.Print("this is like sheet");
        }

        private class GetByCreatia
        {
            public GetByCreatia()
            {
            }

            internal SendCommandCriteria CreateCriteria()
            {
                return new SendCommandCriteria();
            }
        }

        private class SendCommandCriteria
        {
            private int userId;
            private Dictionary<string, Standard> standards = new Dictionary<string, Standard>();
            public SendCommandCriteria()
            {
            }

            public bool Satisfied()
            {
                return true;
            }

            internal void AndUserIdEqualsTo(int v)
            {
                //Satisfied("userId", v);
            }

            private class Standard
            {

            }

            private class ThreadPool
            {
                //to be performant
                private int maxSize = 5;
                private List threads = new List();
                private volatile Action _runable;


                private void StartNew(Action action)
                {
                    this._runable = action;
                    if (threads.Count < maxSize)
                    {
                        var t = new Thread(() => { while (true) { _runable(); Thread.CurrentThread.Suspend(); } });
                        t.Start();
                        threads.Add(t);
                    }
                    else
                    {
                        //exceed equal maxSize
                        var t = threads.First(a => a.IsAlive && a.ThreadState != System.Threading.ThreadState.Running);
                        t.Resume();
                    }

                }
            }

            private class ConnectionPool : IDisposable
            {
                private List pool = new List();
                private int maxSize = 5;
                private DbConnection GetOpenConnection()
                {
                    if (pool.Count < maxSize)
                    {
                        var conn = new SqlConnection();
                        pool.Add(conn);
                        return conn;
                    }
                    else
                    {
                        if (!pool.Any(t => t.State != System.Data.ConnectionState.Open))
                        {
                            throw new DBConcurrencyException("Max reached, no idle connection.");
                        }
                        //==maxSize
                        return pool.First(c => c.State != System.Data.ConnectionState.Open);
                    }
                }

                private bool _disposed = false;
                protected virtual void Dispose(bool disposing)
                {
                    if (_disposed) return;
                    if (disposing)
                    {
                        pool.ForEach(c => c.Dispose());
                    }
                    pool.Clear();
                    _disposed = true;
                }

                public void Dispose()
                {
                    Dispose(true);
                    GC.SuppressFinalize(this);
                }

                ~ConnectionPool()
                {
                    Dispose(false);
                }
            }

            public class Singleton where T : new()
            {
                private Singleton()
                {
                }
                public static T Instance = new T();
            }

            public class Cache : ConcurrentDictionary<string, object>
            {

            }
        }
    }
}
View Code

 

你可能感兴趣的:(Winform Global exception and task parallel library exception;)