c#随笔知识点

文章目录

  • Thread线程
  • Action使用搭配回调函数
  • Task.run和Task.Factory.StartNew比较
  • GC问题(回收)
    • 垃圾回收概念(来之微软官方)
    • 垃圾自动回收优点:
  • 托管和非托管
  • 使用VS2019生成nuget 包:

Thread线程

 public void TestThread()
        {
            ThreadStart threadStart = () => { Init(); };// ThreadStart 是一个委托类型

            Thread thread = new Thread(threadStart);

            thread.Start();//开启线程,执行

            thread.Suspend(); // 线程暂停(被弃用的方法)

            thread.Resume();// 线程恢复(被弃用的方法)

            thread.Abort();// 结束线程

            Thread.ResetAbort(); //恢复被结束的线程

            thread.Join();// 线程等待,这里会卡主正在执行的线程一直等待

            thread.Join(1000);// 线程等待,线程等待一千毫秒

            TimeSpan timeSpan = new TimeSpan();

            int timespan = timeSpan.Seconds;

            thread.Join(timespan);
            
            thread.Priority = ThreadPriority.Highest;// 设置线程的优先级,优先执行但不能代表优先完成,正常的启动的线程等级都是 Normal
            
            thread.IsBackground = false;// 是否为后台线程, false 代表他是一个前台线程,前台线程在进程关闭之后线程要继续运行完才关闭   否则进程关闭线程就关闭
        }
           //
    // 摘要:
    //     指定 System.Threading.Thread 的调度优先级。
    [ComVisible(true)]
    public enum ThreadPriority
    {
        //
        // 摘要:
        //     可以将 System.Threading.Thread 安排在具有任何其他优先级的线程之后。
        Lowest = 0,
        //
        // 摘要:
        //     可以将 System.Threading.Thread 安排在具有 Normal 优先级的线程之后,在具有 Lowest 优先级的线程之前。
        BelowNormal = 1,
        //
        // 摘要:
        //     可以将 System.Threading.Thread 安排在具有 AboveNormal 优先级的线程之后,在具有 BelowNormal 优先级的线程之前。
        //     默认情况下,线程具有 Normal 优先级。
        Normal = 2,
        //
        // 摘要:
        //     可以将 System.Threading.Thread 安排在具有 Highest 优先级的线程之后,在具有 Normal 优先级的线程之前。
        AboveNormal = 3,
        //
        // 摘要:
        //     可以将 System.Threading.Thread 安排在具有任何其他优先级的线程之前。
        Highest = 4
    }
        

单独说一下Suspend()方法和Resume()方法他们一个是暂停线程,一个是恢复被暂停的线程。多线程实际上有我们电脑的CPU来执行的,线程的开始本质上是由CPU决定的。cup空闲的时候我们发出的命令会被很快执行,但是当CPU忙碌的时候就需要等待分配。而我们并不真正清楚他什么时候能开始执行我们需要的线程。所以这两个方法目前已经被微软所弃用。目前也不建议我们再编程的过程当中使用这两个方法来控制线程。

Action使用搭配回调函数

Action是微软自定义的委托方便我们直接使用。它是一个无返回值的可以有入参的委托类型。

 Action action = new Action(() =>
            {
                int i = 0;
                while (true)
                {
                    i++;
                    Console.WriteLine("线程进行中" + i.ToString());
                    System.Threading.Thread.Sleep(2000);
                    if (i > 10)
                    {
                        break;
                    }
                }
            });
            // 回调函数模块
            AsyncCallback asyncCallback = new AsyncCallback(c =>
            {
                int j = 0;
                while (true)
                {
                    j++;
                    Console.WriteLine($"回调函数执行{j}");
                    System.Threading.Thread.Sleep(2000);
                    if (j > 20)
                    {
                        break;
                    }
                }
            });
            IAsyncResult asyncResult = action.BeginInvoke(asyncCallback, null);
            action.EndInvoke(asyncResult);// 运行这句不会阻碍主线程的执行。这句只会等待Action 模块运行完毕之后再去执行回调函数。

//当Action是带参数的委托时:
    Action<int,string> action1 = (x,y) => { Console.WriteLine(x); Console.WriteLine(y);};
  IAsyncResult asyncResult = action.BeginInvoke(1,“朱海不是猪”,asyncCallback, null);// 执行委托并传入参数

Task.run和Task.Factory.StartNew比较

首先是Task.run是在framework4.5才支持使用的。
百度了一下,大家得说法都是Task.Factory.StartNew可以设置线程长时间运行,线程池不会等待改线程的回收。
Task.Factory.StartNew比Task.run更多的参数传入控制,用于设置创建的线程执行状态。

 Task.Factory.StartNew(() =>
            {
                Console.WriteLine("进行 线程" + Thread.CurrentThread.ManagedThreadId.ToString("00"));
            }, TaskCreationOptions.LongRunning);

TaskCreationOptions 枚举类型
c#随笔知识点_第1张图片

Task.run和Task.Factory.StartNew有个共同的地方就是如果要捕捉线程异常是要在内部捕捉的,不可在外层进行异常捕捉。

            try
            {
                Task.Factory.StartNew(()=> { throw new Exception("异常"); });
                  
            }
            catch (Exception e)
            {

                throw;
            }

            try
            {
                Task.Run(() => { throw new Exception("异常"); });

            }
            catch (Exception e)
            {

                throw;
            }

如果像上面这样写是无法捕捉到线程里面的异常的,铭记。(实际跑代码测试过)

GC问题(回收)

垃圾回收概念(来之微软官方)

.NET 的垃圾回收器管理应用程序的内存分配和释放。 每当有对象新建时,公共语言运行时都会从托管堆为对象分配内存。 只要托管堆中有地址空间,运行时就会继续为新对象分配空间。 不过,内存并不是无限的。 垃圾回收器最终必须执行垃圾回收来释放一些内存。 垃圾回收器的优化引擎会根据所执行的分配来确定执行回收的最佳时机。 执行回收时,垃圾回收器会在托管堆中检查应用程序不再使用的对象,然后执行必要的操作来回收其内存。

垃圾自动回收优点:

开发人员不必手动释放内存。

有效分配托管堆上的对象。

回收不再使用的对象,清除它们的内存,并保留内存以用于将来分配。 托管对象会自动获取干净的内容来开始,因此,它们的构造函数不必对每个数据字段进行初始化。

通过确保对象不能使用另一个对象的内容来提供内存安全。

托管和非托管

什么是托管???
微软托管介绍

什么非托管 ???
微软非托管介绍

常见用的非托管资源类型是包装操作系统资源的对象,如文件、窗口、网络连接或数据库连接。
所以我们的常见的使用文件流 和数据库连接会使用using关键字。
提倡使用using关键字就是因为using最后调用了Dispose() 确保了资源的释放。
以下这两段代码,想过相同。

using (var reader = new StringReader(manyLines))
{
    string? item;
    do {
        item = reader.ReadLine();
        Console.WriteLine(item);
    } while(item != null);
}

 var reader = new StringReader(manyLines);
    try {
        string? item;
        do {
            item = reader.ReadLine();
            Console.WriteLine(item);
        } while(item != null);
    } finally
    {
        reader?.Dispose();
    }

使用VS2019生成nuget 包:

1.选择工具->Negut包管理器->程序包管理器控制台
2.cd 到nuget包配置文件路径下面
3.指令:nuget pack

你可能感兴趣的:(c#,java,开发语言)