zoukankan      html  css  js  c++  java
  • Async Concurrent Queue 20120429 add stop Threads

    
    namespace Test
    {
        using System;
        using System.Threading;
        using System.Threading.Tasks;
        using Microshaoft;
        class Program
        {
            static void Main()
            {
                var q = new ConcurrentAsyncQueue<int>();
                q.AttachPerformanceCounters("new");
                Random random = new Random();
                q.OnDequeue += new ConcurrentAsyncQueue<int>.QueueEventHandler
                                                        (
                                                            (x) =>
                                                                {
                                                                    int sleep = random.Next(0, 4) * 500;
                                                                    Thread.Sleep(sleep);
                                                                    //Console.WriteLine(x);
                                                                }
                                                        );
                q.OnException += new ConcurrentAsyncQueue<int>.ExceptionEventHandler
                                                                        (
                                                                            (x) =>
                                                                                {
                                                                                    Console.WriteLine(x.ToString());
                                                                                }
                                                                        );
                Console.WriteLine("begin ...");
                //q.StartAdd(10);
                string r = string.Empty;
                while ((r = Console.ReadLine()) != "q")
                {
                    int i;
                    if (int.TryParse(r, out i))
                    {
                        Console.WriteLine("Parallel Enqueue {0} begin ...", i);
                        new Thread
                                (
                                    new ParameterizedThreadStart
                                                (
                                                    (x) =>
                                                        {
                                                            Parallel.For
                                                                        (
                                                                            0
                                                                            , i
                                                                            , (xx) =>
                                                                            {
                                                                                q.Enqueue(xx);
                                                                            }
                                                                        );
                                                            Console.WriteLine("Parallel Enqueue {0} end ...", i);
                                                        }
                                                )
                                ).Start();
                    }
                    else if (r.ToLower() == "stop")
                    {
                        q.StartStop(10);
                    }
                    else if (r.ToLower() == "add")
                    {
                        q.StartAdd(20);
                    }
                    //else if (r.ToLower() == "count")
                    //{
                    //    q.EnablePerformanceCountersCount = true;
                    //}
                    //else if (r.ToLower() == "uncount")
                    //{
                    //    q.EnablePerformanceCountersCount = false;
                    //}
                    else
                    {
                        Console.WriteLine("please input Number!");
                    }
                }
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Threading;
        using System.Diagnostics;
        using System.Linq;
        using System.Collections.Generic;
        using System.Collections.Concurrent;
        using System.Threading.Tasks;
        using System.Reflection;
        using Microshaoft;
        public class ConcurrentAsyncQueue<T>
        {
            public delegate void QueueEventHandler(T element);
            public event QueueEventHandler OnDequeue;
            public delegate void QueueLogEventHandler(string logMessage);
            public QueueLogEventHandler
                                    OnQueueLog
                                    , OnDequeueThreadStart
                                    , OnDequeueThreadEnd;
            public delegate void ExceptionEventHandler(Exception exception);
            public event ExceptionEventHandler OnException;
            private ConcurrentQueue<T> _queue = new ConcurrentQueue<T>();
            private ConcurrentQueue<Action> _callbackProcessBreaksActions;
            private long _concurrentDequeueThreadsCount = 0; //Microshaoft 用于控制并发线程数
            private ConcurrentQueue<ThreadProcessor> _dequeueThreadsProcessorsPool;
            private int _dequeueIdleSleepSeconds = 10;
            public int DequeueIdleSleepSeconds
            {
                set
                {
                    _dequeueIdleSleepSeconds = value;
                }
                get
                {
                    return _dequeueIdleSleepSeconds;
                }
            }
            private PerformanceCounter _enqueuePerformanceCounter;
            public PerformanceCounter EnqueuePerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _enqueuePerformanceCounter, value);
                }
                get
                {
                    return _enqueuePerformanceCounter;
                }
            }
            private PerformanceCounter _dequeuePerformanceCounter;
            public PerformanceCounter DequeuePerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _dequeuePerformanceCounter, value);
                }
                get
                {
                    return _dequeuePerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueProcessedPerformanceCounter;
            public PerformanceCounter DequeueProcessedPerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _dequeueProcessedPerformanceCounter, value);
                }
                get
                {
                    return _dequeueProcessedPerformanceCounter;
                }
            }
            private PerformanceCounter _queueLengthPerformanceCounter;
            public PerformanceCounter QueueLengthPerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _queueLengthPerformanceCounter, value);
                }
                get
                {
                    return _queueLengthPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueThreadStartPerformanceCounter;
            public PerformanceCounter DequeueThreadStartPerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _dequeueThreadStartPerformanceCounter, value);
                }
                get
                {
                    return _dequeueThreadStartPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueThreadEndPerformanceCounter;
            public PerformanceCounter DequeueThreadEndPerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _dequeueThreadEndPerformanceCounter, value);
                }
                get
                {
                    return _dequeueThreadEndPerformanceCounter;
                }
            }
            private PerformanceCounter _dequeueThreadsCountPerformanceCounter;
            public PerformanceCounter DequeueThreadsCountPerformanceCounter
            {
                private set
                {
                    Interlocked.Exchange<PerformanceCounter>(ref _dequeueThreadsCountPerformanceCounter, value);
                }
                get
                {
                    return _dequeueThreadsCountPerformanceCounter;
                }
            }
            private bool _isAttachedPerformanceCounters = false;
            private class ThreadProcessor
            {
                public bool Break
                {
                    set;
                    get;
                }
                public EventWaitHandle Wait
                {
                    private set;
                    get;
                }
                public ConcurrentAsyncQueue<T> Sender
                {
                    private set;
                    get;
                }
                public void StopOne()
                {
                    Break = true;
                }
                public ThreadProcessor
                                (
                                    ConcurrentAsyncQueue<T> queue
                                    , EventWaitHandle wait
                                )
                {
                    Wait = wait;
                    Sender = queue;
                }
                public void ThreadProcess()
                {
                    Interlocked.Increment(ref Sender._concurrentDequeueThreadsCount);
                    if (Sender._isAttachedPerformanceCounters)
                    {
                        Sender.DequeueThreadStartPerformanceCounter.Increment();
                        Sender.DequeueThreadsCountPerformanceCounter.Increment();
                    }
                    long r = 0;
                    try
                    {
                        if (Sender.OnDequeueThreadStart != null)
                        {
                            r = Interlocked.Read(ref Sender._concurrentDequeueThreadsCount);
                            Sender.OnDequeueThreadStart
                                            (
                                                string.Format
                                                        (
                                                            "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
                                                            , "Threads ++ !"
                                                            , r
                                                            , Sender._queue.Count
                                                            , Thread.CurrentThread.Name
                                                            , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
                                                        )
                                            );
                        }
                        while (true)
                        {
                            #region while true
                            if (Break)
                            {
                                break;
                            }
                            while (!Sender._queue.IsEmpty)
                            {
                                #region while queue.IsEmpty
                                if (Break)
                                {
                                    break;
                                }
                                T element;
                                if (Sender._queue.TryDequeue(out element))
                                {
                                    if (Sender._isAttachedPerformanceCounters)
                                    {
                                        Sender.DequeuePerformanceCounter.Increment();
                                        Sender.QueueLengthPerformanceCounter.Decrement();
                                    }
                                    if (Sender.OnDequeue != null)
                                    {
                                        Sender.OnDequeue(element);
                                    }
                                    if (Sender._isAttachedPerformanceCounters)
                                    {
                                        Sender.DequeueProcessedPerformanceCounter.Increment();
                                    }
                                }
                                #endregion while queue.IsEmpty
                            }
                            #region wait
                            Sender._dequeueThreadsProcessorsPool.Enqueue(this);
                            if (Break)
                            {
                            }
                            if (!Wait.WaitOne(Sender.DequeueIdleSleepSeconds * 1000))
                            {
                            }
                            #endregion wait
                            #endregion while 1 == 1
                        }
                    }
                    catch (Exception e)
                    {
                        if (Sender.OnException != null)
                        {
                            Sender.OnException(e);
                        }
                    }
                    finally
                    {
                        r = Interlocked.Decrement(ref Sender._concurrentDequeueThreadsCount);
                        if (r < 0)
                        {
                            Interlocked.Exchange(ref Sender._concurrentDequeueThreadsCount, 0);
                            if (Sender._isAttachedPerformanceCounters)
                            {
                                if (Sender.DequeueThreadsCountPerformanceCounter.RawValue < 0)
                                {
                                    Sender.DequeueThreadsCountPerformanceCounter.RawValue = Sender._concurrentDequeueThreadsCount;
                                }
                            }
                        }
                        if (Sender.OnDequeueThreadEnd != null)
                        {
                            Sender.OnDequeueThreadEnd
                                        (
                                            string.Format
                                                    (
                                                        "{0} Threads Count {1},Queue Count {2},Current Thread: {3} at {4}"
                                                        , "Threads--"
                                                        , r
                                                        , Sender._queue.Count
                                                        , Thread.CurrentThread.Name
                                                        , DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffff")
                                                    )
                                        );
                        }
                        if (Sender._isAttachedPerformanceCounters)
                        {
                            Sender.DequeueThreadEndPerformanceCounter.Increment();
                            Sender.DequeueThreadsCountPerformanceCounter.Decrement();
                        }
                        if (!Break)
                        {
                            Sender.StartAdd(1);
                        }
                        Break = false;
                    }
                }
            }
            public void AttachPerformanceCounters(string instanceNamePrefix)
            {
                var category = "Microshaoft AsyncConurrentQueue Counters";
                var process = Process.GetCurrentProcess();
                var processName = process.ProcessName;
                var instanceName = string.Format
                                        (
                                            "{0}-{1}"
                                            , instanceNamePrefix
                                            , processName
                    //, processID
                    //, processStartTime.ToString("yyyy-MM-dd HH:mm:ss.fff")
                                        );
                var type = this.GetType();
                PerformanceCountersHelper.AttachPerformanceCountersToProperties<ConcurrentAsyncQueue<T>>(instanceName, category, this);
                _isAttachedPerformanceCounters = true;
            }
            public int Count
            {
                get
                {
                    return _queue.Count;
                }
            }
            public long ConcurrentThreadsCount
            {
                get
                {
                    return _concurrentDequeueThreadsCount;
                }
            }
            private void Stop(int count)
            {
                Action action;
                for (var i = 0; i < count; i++)
                {
                    if (_callbackProcessBreaksActions.TryDequeue(out action))
                    {
                        action();
                    }
                }
            }
            public void StartStop(int count)
            {
                new Thread
                        (
                            new ThreadStart
                                    (
                                        () =>
                                            {
                                                Stop(count);
                                            }
                                    )
                        ).Start();
            }
            public void StartAdd(int count)
            {
                new Thread
                        (
                            new ThreadStart
                                    (
                                        () =>
                                            {
                                                Add(count);
                                            }
                                    )
                        ).Start();
            }
            private void Add(int count)
            {
                for (int i = 0; i < count; i++)
                {
                    Interlocked.Increment(ref _concurrentDequeueThreadsCount);
                    if (_dequeueThreadsProcessorsPool == null)
                    {
                        _dequeueThreadsProcessorsPool = new ConcurrentQueue<ThreadProcessor>();
                    }
                    var processor = new ThreadProcessor
                                                    (
                                                        this
                                                        , new AutoResetEvent(false)
                                                    );
                    var thread = new Thread
                                        (
                                            new ThreadStart
                                                        (
                                                            processor.ThreadProcess
                                                        )
                                        );
                    if (_callbackProcessBreaksActions == null)
                    {
                        _callbackProcessBreaksActions = new ConcurrentQueue<Action>();
                    }
                    var callbackProcessBreakAction = new Action
                                                    (
                                                        processor.StopOne
                                                    );
                    _callbackProcessBreaksActions.Enqueue(callbackProcessBreakAction);
                    _dequeueThreadsProcessorsPool.Enqueue(processor);
                    thread.Start();
                }
            }
            public void Enqueue(T element)
            {
                try
                {
                    _queue.Enqueue(element);
                    if (_isAttachedPerformanceCounters)
                    {
                        EnqueuePerformanceCounter.Increment();
                        QueueLengthPerformanceCounter.Increment();
                    }
                    if
                        (
                            _dequeueThreadsProcessorsPool != null
                            && !_dequeueThreadsProcessorsPool.IsEmpty
                        )
                    {
                        ThreadProcessor processor;
                        if (_dequeueThreadsProcessorsPool.TryDequeue(out processor))
                        {
                            processor.Wait.Set();
                        }
                    }
                }
                catch (Exception e)
                {
                    if (OnException != null)
                    {
                        OnException(e);
                    }
                }
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Linq;
        using System.Diagnostics;
        using System.Reflection;
        using System.Collections.Generic;
        public static class PerformanceCountersHelper
        {
            public static void AttachPerformanceCountersToProperties<T>
                                        (
                                            string performanceCounterInstanceName
                                            , string category
                                            , T target = default(T)
                                        )
            {
                var type = typeof(T);
                var propertiesList = type.GetProperties().ToList();
                propertiesList = propertiesList.Where
                                                    (
                                                        (pi) =>
                                                        {
                                                            return (pi.PropertyType == typeof(PerformanceCounter));
                                                        }
                                                    ).ToList();
                if (PerformanceCounterCategory.Exists(category))
                {
                    propertiesList.ForEach
                                        (
                                            (pi) =>
                                            {
                                                if (PerformanceCounterCategory.CounterExists(pi.Name, category))
                                                {
                                                    if (PerformanceCounterCategory.InstanceExists(performanceCounterInstanceName, category))
                                                    {
                                                        //var pc = new PerformanceCounter(category, pi.Name, instanceName, false);
                                                        //pc.InstanceName = instanceName;
                                                        //pc.RemoveInstance();
                                                    }
                                                }
                                            }
                                        );
                    PerformanceCounterCategory.Delete(category);
                }
                var ccdc = new CounterCreationDataCollection();
                propertiesList.ForEach
                                (
                                    (pi) =>
                                        {
                                            var propertyName = pi.Name;
                                            var ccd = PerformanceCounterHelper.GetCounterCreationData
                                            (
                                                propertyName
                                                , PerformanceCounterType.NumberOfItems64
                                            );
                                            ccdc.Add(ccd);
                                        }
                                );
                PerformanceCounterCategory.Create
                                (
                                    category,
                                    string.Format("{0} Category Help.", category),
                                    PerformanceCounterCategoryType.MultiInstance,
                                    ccdc
                                );
                propertiesList.ForEach
                                (
                                    (pi) =>
                                    {
                                        var propertyName = pi.Name;
                                        var pc = new PerformanceCounter()
                                        {
                                            CategoryName = category
                                            , CounterName = propertyName
                                            , InstanceLifetime = PerformanceCounterInstanceLifetime.Process
                                            , InstanceName = performanceCounterInstanceName
                                            , ReadOnly = false
                                            , RawValue = 0
                                        };
                                        if (pi.GetGetMethod().IsStatic)
                                        {
                                            var setter = DynamicPropertyAccessor.CreateSetStaticPropertyValueAction<PerformanceCounter>(type, propertyName);
                                            setter(pc);
                                        }
                                        else
                                        {
                                            if (target != null)
                                            {
                                                var setter = DynamicPropertyAccessor.CreateSetPropertyValueAction<PerformanceCounter>(type, propertyName);
                                                setter(target, pc);
                                            }
                                        }
                                    }
                                );
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Diagnostics;
        public static class PerformanceCounterHelper
        {
            public static CounterCreationData GetCounterCreationData(string counterName, PerformanceCounterType performanceCounterType)
            {
                return new CounterCreationData()
                {
                    CounterName = counterName
                    , CounterHelp = string.Format("{0} Help", counterName)
                    , CounterType = performanceCounterType
                };
            }
        }
    }
    namespace Microshaoft
    {
        using System;
        using System.Reflection;
        using System.Linq;
        using System.Linq.Expressions;
        public class DynamicPropertyAccessor
        {
            public static Func<object, object> CreateGetPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateGetPropertyValueFunc(type, propertyName);
            }
            public static Func<object, object> CreateGetPropertyValueFunc(Type type, string propertyName)
            {
                var target = Expression.Parameter(typeof(object));
                var castTarget = Expression.Convert(target, type);
                var getPropertyValue = Expression.Property(castTarget, propertyName);
                var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
                var lambda = Expression.Lambda<Func<object, object>>(castPropertyValue, target);
                return lambda.Compile();
            }
            public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateGetPropertyValueFunc<TProperty>(type, propertyName);
            }
            public static Func<object, TProperty> CreateGetPropertyValueFunc<TProperty>(Type type, string propertyName)
            {
                var target = Expression.Parameter(typeof(object));
                var castTarget = Expression.Convert(target, type);
                var getPropertyValue = Expression.Property(castTarget, propertyName);
                var lambda = Expression.Lambda<Func<object, TProperty>>(getPropertyValue, target);
                return lambda.Compile();
            }
            public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateGetStaticPropertyValueFunc<TProperty>(type, propertyName);
            }
            public static Func<TProperty> CreateGetStaticPropertyValueFunc<TProperty>(Type type, string propertyName)
            {
                var property = type.GetProperty(propertyName, typeof(TProperty));
                var getPropertyValue = Expression.Property(null, property);
                var lambda = Expression.Lambda<Func<TProperty>>(getPropertyValue, null);
                return lambda.Compile();
            }
            public static Func<object> CreateGetStaticPropertyValueFunc(Type type, string propertyName)
            {
                var property = type.GetProperty(propertyName);
                var getPropertyValue = Expression.Property(null, property);
                var castPropertyValue = Expression.Convert(getPropertyValue, typeof(object));
                var lambda = Expression.Lambda<Func<object>>(castPropertyValue, null);
                return lambda.Compile();
            }
            public static Func<object> CreateGetStaticPropertyValueFunc(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateGetStaticPropertyValueFunc(type, propertyName);
            }
            public static Action<object, object> CreateSetPropertyValueAction(Type type, string propertyName)
            {
                var property = type.GetProperty(propertyName);
                var target = Expression.Parameter(typeof(object));
                var propertyValue = Expression.Parameter(typeof(object));
                var castTarget = Expression.Convert(target, type);
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object, object>>(call, target, propertyValue);
                return lambda.Compile();
            }
            public static Action<object, object> CreateSetPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetPropertyValueAction(type, propertyName);
            }
            public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(Type type, string propertyName)
            {
                var property = type.GetProperty(propertyName);
                var target = Expression.Parameter(typeof(object));
                var propertyValue = Expression.Parameter(typeof(TProperty));
                var castTarget = Expression.Convert(target, type);
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(castTarget, getSetMethod, castPropertyValue);
                return Expression.Lambda<Action<object, TProperty>>(call, target, propertyValue).Compile();
            }
            public static Action<object, TProperty> CreateSetPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetPropertyValueAction<TProperty>(type, propertyName);
            }
            public static Action<object> CreateSetStaticPropertyValueAction(Type type, string propertyName)
            {
                var property = type.GetProperty(propertyName);
                var propertyValue = Expression.Parameter(typeof(object));
                var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(null, getSetMethod, castPropertyValue);
                var lambda = Expression.Lambda<Action<object>>(call, propertyValue);
                return lambda.Compile();
            }
            public static Action<object> CreateSetStaticPropertyValueAction(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetStaticPropertyValueAction(type, propertyName);
            }
            public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(Type type, string propertyName)
            {
                var property = type.GetProperty(propertyName);
                var propertyValue = Expression.Parameter(typeof(TProperty));
                //var castPropertyValue = Expression.Convert(propertyValue, property.PropertyType);
                var getSetMethod = property.GetSetMethod();
                if (getSetMethod == null)
                {
                    getSetMethod = property.GetSetMethod(true);
                }
                var call = Expression.Call(null, getSetMethod, propertyValue);
                var lambda = Expression.Lambda<Action<TProperty>>(call, propertyValue);
                return lambda.Compile();
            }
            public static Action<TProperty> CreateSetStaticPropertyValueAction<TProperty>(string typeName, string propertyName, bool isTypeFromAssembly = false)
            {
                Type type;
                if (isTypeFromAssembly)
                {
                    var assembly = AppDomain.CurrentDomain.GetAssemblies().First
                                                                    (
                                                                        (a) =>
                                                                            {
                                                                                return a.GetTypes().Any
                                                                                                    (
                                                                                                        (t) =>
                                                                                                            {
                                                                                                                return (t.FullName == typeName);
                                                                                                            }
                                                                                                    );
                                                                            }
                                                                    );
                    type = assembly.GetType(typeName);
                }
                else
                {
                    type = Type.GetType(typeName);
                }
                return CreateSetStaticPropertyValueAction<TProperty>(type, propertyName);
            }
        }
    }
    
    
  • 相关阅读:
    【leetcode】Binary Search Tree Iterator
    【leetcode】Palindrome Partitioning II
    【leetcode】Best Time to Buy and Sell Stock III
    【leetcode】Best Time to Buy and Sell Stock II
    【leetcode】Longest Consecutive Sequence
    【leetcode】Factorial Trailing Zeroes
    【leetcode】Simplify Path
    【leetcode】Generate Parentheses
    【leetcode】Combination Sum II
    【leetcode】Combination Sum
  • 原文地址:https://www.cnblogs.com/Microshaoft/p/2475897.html
Copyright © 2011-2022 走看看