C#

C#: 一个方法执行超时 timeout 检查的实现

我们经常有这样的需求:如果一个方法的执行,超过了一个设定时间(timeout)就需要立即返回不再继续,这里我利用 C# 异步委托的 AsyncWaitHandle 来尽量简便的实现这一需求。

具体实现如下。注意,这里需要被调用的方法遵守 delegate TR TimeOutDelegate(T param); 形式的方法签名,如有其他需要,可以自行定制也很方便。

namespace TimeOutHelper
{
    #region using directives

    using System;
    using System.Collections.Generic;
    using System.Globalization;
    using System.Linq;
    using System.Threading;

    #endregion using directives

    internal class Program
    {
        public delegate TR TimeOutDelegate<in T, out TR>(T param);

        private static void Main()
        {
            Dictionary<Guid, string> result;
            Console.WriteLine(TimeoutFunction.Execute(Test, "Hello, World!", out result, TimeSpan.FromSeconds(3)));
            Console.WriteLine("Hello, World!");
            Console.ReadKey();
        }

        public static Dictionary<Guid, string> Test(string sourceString)
        {
            var result = sourceString.ToDictionary(
                character => Guid.NewGuid(),
                character => character.ToString(CultureInfo.InvariantCulture));
            Thread.Sleep(4000);
            return result;
        }

        public static class TimeoutFunction
        {
            /// <summary>
            ///     Execute a method with timeout check
            /// </summary>
            /// <typeparam name="T">Target method parameter type</typeparam>
            /// <typeparam name="TR">The result type of execution</typeparam>
            /// <param name="timeoutMethod">Target method</param>
            /// <param name="param">Target method parameter</param>
            /// <param name="result">The result of execution</param>
            /// <param name="timeout">Set timeout length</param>
            /// <returns>Is timeout</returns>
            public static Boolean Execute<T, TR>(
                TimeOutDelegate<T, TR> timeoutMethod, T param, out TR result, TimeSpan timeout)
            {
                var asyncResult = timeoutMethod.BeginInvoke(param, null, null);
                if (!asyncResult.AsyncWaitHandle.WaitOne(timeout, false))
                {
                    result = default(TR);
                    return true;
                }
                result = timeoutMethod.EndInvoke(asyncResult);
                return false;
            }
        }
    }
}

C#: 字符串连接 (+=) 与 StringBuilder 效率分析

在 C# 或 Java 中,我们可以使用诸如 StringBuilder, StringBuffer 等方式对大量字符串进行拼接操作。当然,我们也可以直接使用 字符串连接 (+=) 的方式进行拼接操作。但是,两种主要方式在效率上有何区别呢?我们是否需要针对这两类方式进行区别场景的使用呢?针对于此,我做了如下测试,以证明两种不同方式连接字符串的效率临界值。(关于Java中StringBuilder和StringBuffer的区别,可以参阅这篇文章

测试方法是:重复连接字符串 “Hello World!” 1次到40次,在每次连接的过程中都分别采用 String Connection (+=) 和 StringBuilder 的 Append()方法进行1000次,并分别计算出两种方法在这1000次运算过程中的获胜比率。通过多次试验,得到如下统计:

第一次:
StringBuilder Efficiency Test 1
Continue reading

C#: 双检锁 (Double Checked Locking)

以下内容是我在公司作为新人培训讲师时对于作业的一次评价,简单介绍了双解锁的作用,可以作为一个简单的参考。

大家可以思考这样一个问题,一个程序可以对应多少个日志文件?对于我们这个小程序来说1个就够了,很多同学在设计Logger类的时候都是在构造方法或初始化方法中生成日志文件的,也就是说,这基本上等价于一个Logger的实例对应一个新的日志文件(或重新对同一文件重新开启流)。

Logger myLogger = new Logger(@“D:my.log”);

如何才能阻止Logger被随意的new出实例呢?我们可以修改Logger的构造方法,让构造方法成为private的,这样就能实现谁都不能new出Logger实例的目的了。但是,访问修饰符(如private)只是影响类之外的使用,对于Logger类的内部,是不会受到private的影响的,也就是说,我们依然可以在Logger类中使用new来创建实例,这正是我们想要的,我们可以为用户提前创建好一个实例,并作为这个类的静态成员存在,从而得到这样一个Logger类:
Continue reading