03
2017
06

.Net快速获取网络文本文件最后一段文字-小应用

场景


现在公司的测试环境一些文本日志不让接触,提供一个网络http服务器让人直接访问,这文件大时,一般10MB一个文件,不在同一局域网,网速限制200K,要等很久,访问很慢。


.Net代码请求文本文件最新内容(类似于tail文件)

06
2017
01

单例模式的优化-双重锁定

三种单例模式写法:

    public class Singleton
    {
        private static Singleton instance;
        private static readonly object syncRoot = new object();
        private Singleton() { }
        public static Singleton GetInstance()
        {
            if (instance == null)//Double-Check Locking 双重锁定,比直接lock性能更好,最完美的模式(懒汉式单例)
            {
                lock (syncRoot)
                {
                    if (instance == null)
                    {
                        instance = new Singleton();
                    }
                }
            }
            return instance;
        }
    }
    public class Singleton1
    {
        private static Singleton1 instance;
        private static readonly object syncRoot = new object();
        private Singleton1() { }
        public static Singleton1 GetInstance()
        {
            lock (syncRoot)//每次调用GetInstance都需要lock,影响性能(懒汉式单例)
            {
                if (instance == null)
                {
                    instance = new Singleton1();
                }
            }
            return instance;
        }
    }
    public class Singleton2
    {
        private static Singleton2 instance=new Singleton2();//静态初始化方式(饿汉式单例),类一加载就实例化对象,一般这样用也没问题,缺点:提前占用系统资源
        private Singleton2() { }
        public static Singleton2 GetInstance()
        {
            return instance;
        }
    }

27
2016
12

.Net函数Math.Round你会用吗?

一直以为Math.Round就是四舍五入,谁知道没加参数,得到的结果就是有问题


测试代码:

void Main()
{
    string.Format("Round  {0} = {1}",2.4M,Math.Round(2.4M,0)).Dump();
    string.Format("Round  {0} = {1}",2.5M,Math.Round(2.5M,0)).Dump();
    string.Format("Round  {0} = {1}",2.6M,Math.Round(2.6M,0)).Dump();
    string.Format("Round  {0} = {1}",3.4M,Math.Round(3.4M,0)).Dump();
    string.Format("Round  {0} = {1}",3.5M,Math.Round(3.5M,0)).Dump();
    string.Format("Round  {0} = {1}",3.6M,Math.Round(3.6M,0)).Dump();
}

输出内容:

25
2016
11

.Net中偶尔需要使用异步的处理

我们知道程序中使用异步、多线程会提高程序的响应速度,但也不能无限使用多线程,这在高峰会造成系统cpu上升,系统卡顿,这就需要我们自己来控制开启的线程数,不多说看代码。

        private static int threadCountByOrderId = 0;
        private static int maxThreadCountByOrderId = 30;
        public bool dealorder(int OrderId)
        {
            var threadNumber = Interlocked.Exchange(ref threadCountByOrderId, threadCountByOrderId);
            if (threadCountByOrderId > maxThreadCountByOrderId)
            {
                return OrderChangePushToBigDataImpService.PushOrderToBigData(OrderId, Logger);
            }
            else
            {
                Task.Factory.StartNew(() =>
                {
                    Interlocked.Increment(ref threadCountByOrderId);
                    try
                    {
                        using (var context = MefInjectionProvider.CreateContext())
                        {
                            var NewOrderChangePushToBigDataImpService = context.Value.GetExport<IOrderChangePushToBigDataImpService>();
                            NewOrderChangePushToBigDataImpService.PushOrderToBigData(OrderId, Logger);
                        }
                    }
                    finally
                    {
                        Interlocked.Decrement(ref threadCountByOrderId);
                    }
                });
                return true;
            }
        }

这样就能控制线程数据了

11
2016
10

.Net中自动生成Model字段修改日志内容

直接上代码,传入新旧两个Model类


字段说明,要加display标签: 

代码如下:

    public static class EntityExtension
    {
        public static HashSet<Type> PrimitiveTypes = null;
        static EntityExtension()
        {
            PrimitiveTypes = new HashSet<Type>()
                {
                    typeof(String),
                    typeof(Byte[]),
                    typeof(Byte),
                    typeof(Int16),
                    typeof(Int32),
                    typeof(Int64),
                    typeof(Single),
                    typeof(Double),
                    typeof(Decimal),
                    typeof(DateTime),
                    typeof(Guid),
                    typeof(Boolean),
                    typeof(TimeSpan),
                    typeof(Byte?),
                    typeof(Int16?),
                    typeof(Int32?),
                    typeof(Int64?),
                    typeof(Single?),
                    typeof(Double?),
                    typeof(Decimal?),
                    typeof(DateTime?),
                    typeof(Guid?),
                    typeof(Boolean?),
                    typeof(TimeSpan?)
                };
        }
        public static string GetChangedFields<T>(this T newEntity, T oldEntity) where T : class
        {
            StringBuilder updatedFields = new StringBuilder();
            Type entityType = typeof(T);
            PropertyInfo[] properties = entityType.GetProperties().Where(o => o.CanWrite && PrimitiveTypes.Contains(o.PropertyType) && !o.GetCustomAttributes(false).OfType<NotMappedAttribute>().Any()).ToArray();
            foreach (var p in properties)
            {
                if (p.Name == "ModifiedDate" || p.Name == "ModifiedByName" || p.Name == "ModifiedById") continue;
                object oldValue = p.GetValue(oldEntity, null);
                object newValue = p.GetValue(newEntity, null);
                if ((oldValue == null && newValue == null))
                {
                    continue;
                }
                else if (oldValue == null && newValue != null || oldValue != null && newValue == null || !Eq(p.PropertyType, oldValue, newValue))
                {
                    string fieldName;
                    var display = p.GetCustomAttribute<DisplayAttribute>(false);
                    fieldName = display != null ? display.Name : p.Name;
                    updatedFields.AppendFormat("{0}:{1}->{2}; ", fieldName, oldValue ?? "NULL", newValue ?? "NULL");
                }
            }
            return updatedFields.ToString();
        }
        private static bool Eq(Type propertyType, object oldValue, object newValue)
        {
            if (propertyType == typeof(Decimal) || propertyType == typeof(Decimal?))
            {
                return decimal.Parse(oldValue.ToString()) == decimal.Parse(newValue.ToString());
            }
            else
            {
                return string.Equals(oldValue.ToString(), newValue.ToString());
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="newEntity"></param>
        /// <param name="oldEntity"></param>
        /// <returns></returns>
        public static List<ValueModifiedModel> GetChangedFieldsExtent<T>(this T newEntity, T oldEntity) where T : class
        {
            List<ValueModifiedModel> valueModifiedList = new List<ValueModifiedModel>();
            Type entityType = typeof(T);
            PropertyInfo[] properties = entityType.GetProperties().Where(o => o.CanWrite && PrimitiveTypes.Contains(o.PropertyType) && !o.GetCustomAttributes(false).OfType<NotMappedAttribute>().Any()).ToArray();
            foreach (var p in properties)
            {
                if (ignoreColumnList.Contains(p.Name))
                    continue;
                object oldValue = p.GetValue(oldEntity, null);
                object newValue = p.GetValue(newEntity, null);
                if ((oldValue == null && newValue == null))
                {
                    continue;
                }
                else if (oldValue == null && newValue != null || oldValue != null && newValue == null || !Eq(p.PropertyType, oldValue, newValue))
                {
                    valueModifiedList.Add(new ValueModifiedModel()
                    {
                        ColumnName = p.Name,
                        ColumnChineseName = p.GetPropertyDisplayName(),
                        ChangeBefore = oldValue ?? "NULL",
                        ChangeAfter = newValue ?? "NULL"
                    }
                    );
                }
            }
            return valueModifiedList;
        }
        /// <summary>
        /// /
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="pTargetObjSrc"></param>
        /// <param name="pTargetObjDest"></param>
        public static void EntityToEntity<T>(T pTargetObjSrc, T pTargetObjDest) where T : class
        {
            try
            {
                foreach (var mItem in typeof(T).GetProperties())
                {
                    mItem.SetValue(pTargetObjDest, mItem.GetValue(pTargetObjSrc, new object[] { }), null);
                }
            }
            catch (NullReferenceException NullEx)
            {
                throw NullEx;
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }
        /// <summary>
        /// 忽略的列名列表
        /// </summary>
        public static List<string> ignoreColumnList = new List<string>()
        {
        };
    }


31
2016
08

.Net框架搭建之辅助模版代码生成工具


在.Net框架搭建讲解中,提到了代码自动生成来减少开发人员人工作量,比如数据库对应的Model、最基层的Repository类和接口等等,除了类名不一样,其他都一样,没必要再手写一遍。 

我在这里,介绍使用CodeSmith模版生成Model类,其他的都一样,拿到表名和各字段名、字段类型等等,想怎么生成就能怎么生成。


首先,在硬盘中,建立一个文件夹,用来放模版文件,比如: 

F:\pukuimin\InjectExample\ExampleCodeSmithTemplate 

26
2016
08

[转载]在Web.config或App.config中的添加自定义配置

.Net中的System.Configuration命名空间为我们在web.config或者app.config中自定义配置提供了完美的支持。最近看到一些项目中还在自定义xml文件做程序的配置,所以忍不住写一篇用系统自定义配置的随笔了。


如果你已经对自定义配置了如指掌,请忽略这篇文章。


言归正传,我们先来看一个最简单的自定义配置

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="simple" type="ConfigExample.Configuration.SimpleSection,ConfigExample"/>
  </configSections>
  <simple maxValue="20" minValue="1"></simple>
</configuration>

在配置文件中使用自定义配置,需要在configSections中添加一个section元素,并制定此section元素对应的类型和名字。然后再在configuration根节点下面添加此自定义配置,如上例中的simple节点。simple节点只有两个整形数的属性maxValue和minValue。

24
2016
08

EpPlus读取生成Excel帮助类+读取csv帮助类+Aspose.Cells生成Excel帮助类

大部分功能逻辑都在,少量自定义异常类和扩展方法 ,可用类似代码自己替换

//EpPlus读取生成Excel帮助类+读取csv帮助类,epplus只支持开放的Excel文件格式:xlsx,不支持 xls格式

24
2016
08

[转载]Expression 表达式树学习整理

整理了一下表达式树的一些东西,入门足够了


先从ConstantExpression 开始一步一步的来吧  它表示具有常量值的表达式


我们选建一个控制台应用程序

ConstantExpression _constExp = Expression.Constant("aaa",typeof(string));//一个常量
//Console.Writeline("aaa");
MethodCallExpression _methodCallexp=Expression.Call(typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}),_constExp);
Expression<Action> consoleLambdaExp = Expression.Lambda<Action>(_methodCallexp);
consoleLambdaExp.Compile()();
 
Console.ReadLine();

下边的MethodCallExpression你也许不知道是什么回事,不要急我下边会详细讲的,这相当于

18
2016
08

.Net最简单的创建多线程主线程等待所有线程执行完成的例子

多线程运行,主线程等待。

        private static void Test2()
        {
            var waits = new List<EventWaitHandle>();
            for (int i = 0; i < 10; i++)
            {
                var handler = new ManualResetEvent(false);
                waits.Add(handler);
                new Thread(new ParameterizedThreadStart(Print))
                {
                    Name = "thread" + i.ToString()
                }.Start(new Tuple<int, EventWaitHandle>(i, handler));
            }
            WaitHandle.WaitAll(waits.ToArray());
            Console.WriteLine("All Completed!");
            Console.Read();
        }
        private static void Print(object param)
        {
            var p = (Tuple<int, EventWaitHandle>)param;
            Console.WriteLine(Thread.CurrentThread.Name + ": Begin!");
            if (p.Item1 == 2) Thread.Sleep(1200);
            else if (p.Item1 ==1 ) Thread.Sleep(2000);
            else Thread.Sleep(1000);
            Console.WriteLine(Thread.CurrentThread.Name + ": Print" + p.Item1);
            Console.WriteLine(Thread.CurrentThread.Name + ": End!");
            p.Item2.Set();
        }