2021年7月24日 星期六

c# 新增資料後寫Log

之前有寫了一篇文章EntityFrame SaveChange之後寫Log (Entity Framework 資料異動寫入Log)
但是世界沒有這麼美好,客戶想要各種的客製化Log,讓這個覆寫SaveChange不堪使用
幾乎是無用武之地,客戶已經沒這麼好騙了,幾乎每個Table新增時都要有各種花式寫Log
於是想了一個概念,如下面的Example,也不知道好不好
 
namespace ConsoleApp1
{
    class Program
    {
        static void Main(string[] args)
        {
            var test1 = new Test1();
            test1.SaveChange(new TestModel
            {
                Name = "1234",
                Mail = "1234@gmial.com"
            });

            var test2 = new Test2();
            test2.SaveChange(new TestModel
            {
                Name = "5678",
                Mail = "5678@gmial.com"
            });
            Console.ReadLine();
        }

    }

    public class TestModel
    {
        public string Name { get; set; }
        public string Mail { get; set; }
    }


    public interface ITest<TModel>
    {
        int SaveChange(TModel model);
    }

    public class Test1 : TestBase, ITest<TestModel>
    {
        public int SaveChange(TestModel model)
        {
            //EF Savechange
            //不特別處理Log
            base.AddLog(model);
            return 1;
        }
    }

    public class Test2 : TestBase, ITest<TestModel>
    {
        public int SaveChange(TestModel model)
        {
            //EF Savechange
            this.AddLog(model);
            return 1;
        }

        protected override void AddLog<TModel>(TModel model)
        {
            //需要特別處理Log
            var specModel = model as TestModel;
            specModel.Name += "特別處理";
            specModel.Mail += "特別處理";
            Console.WriteLine(JsonConvert.SerializeObject(model));
        }
    }


    public class TestBase
    {
        protected virtual void AddLog<TModel>(TModel model)
        {
            Console.WriteLine(JsonConvert.SerializeObject(model));
        }
    }
}
這邊就是把SaveChange再拉出一層做一些包裝
使用者依然是無腦的使用SaveChange寫入資料
但是裡面的SaveChange會再去呼叫AddLog
每個類別可以對AddLog覆寫實作,已達到客戶的各種客製化寫Log
不知道有沒有更好的想法

2021年7月4日 星期日

c# Task 多執行緒

以前太淺再跑多執行緒都沒再限制Task的數量
所以一跑下去整台主機就卡給你看
因為把資源通通吃光了,那c#怎麼控制你想要的數量呢

使用SemaphoreSlim
 
class Program
    {
        private static readonly SemaphoreSlim Locker = new SemaphoreSlim(5);

        static async Task Main(string[] args)
        {
            List<Task> tasks = new List<Task>();
            for (int i = 0; i < 100; i++)            
                tasks.Add(Task.Run(() => TaskRun()));

            await Task.WhenAll(tasks);
        }

        public static Task TaskRun()
        {
            Locker.Wait();
            return Task.Run(async () =>
            {
                await Task.Run(() =>
                {
                    Console.WriteLine($"{DateTime.Now:yyyy-MM-dd HH:mm:ss}_Do work.");
                    Thread.Sleep(3000);
                })
                .ConfigureAwait(false);
                Locker.Release();
            });
        }
    }

我起了100個Task因為使用SemaphoreSlim限制每次只跑5個執行緒
所以每次最多就會執行5個,這樣就不會狂跑把主機資源都吃光光