shuai's profile娱乐精神PhotosBlog Tools Help

Blog


    6/10/2006

    限制创建线程个数的线程管理器

    限制创建线程个数的线程管理器,可以算是线程模式最常用的一种了,做的通用了一点,但是我觉得AbstractThreadWorker可能会时常被修改,有点地方做的对调用者隐藏的还不是太好
     
    框架代码:
     
    public delegate void CallbackDoWorkEnd();
     
    //工作线程接口 
    interface IThreadWorker
    {
        void Run();
        ThreadManager ThreadManager
        {
            get;
            set;
        }
        IThreadWorkerOption RunOption
        {
            set;
        }
    }
     
    //用于为工作线程传递的参数,需要继承IThreadWorkerOption
    interface IThreadWorkerOption
    {
     
    }
     
     
    //控制创建的线程个数
    class ThreadManager
    {
        public ThreadManager()
        {
            MaxThreadNum = 10;
        }
        public void Run(IThreadWorker threadWorker, IThreadWorkerOption runOption)
        {
            if (_currentThreadNum >= MaxThreadNum)
            {
                Suspend();
            }
            threadWorker.RunOption = runOption;
            threadWorker.ThreadManager = this;
            Thread thread = new Thread(new ThreadStart(threadWorker.Run));
            thread.Start();
            Interlocked.Increment(ref _currentThreadNum);

        }
        public void Resume(CallbackDoWorkEnd callbackDoWorkEnd)
        {
            Monitor.Enter(this);
            Interlocked.Decrement(ref _currentThreadNum);
            if (_currentThreadNum < MaxThreadNum)
            {
                Monitor.Pulse(this);
            }
            callbackDoWorkEnd();
            Monitor.Exit(this);
        }
        public void Suspend()
        {
            Monitor.Enter(this);
            Monitor.Wait(this);
            Monitor.Exit(this);
        }
        public int CurrentThreadNum
        {
            get { return _currentThreadNum; }
        }
        public int MaxThreadNum
        {
            get { return _maxThreadNum; }
            set { _maxThreadNum = value; }
        }
        public int _maxThreadNum;
        public int _currentThreadNum = 0;
    }
     
    //工作线程需要继承AbstractThreadWorker
    abstract class AbstractThreadWorker : IThreadWorker
    {
        abstract public void DoWork();
        abstract public void DoWorkEnd();
        protected CallbackDoWorkEnd _callbackDoWorkEnd;
        public AbstractThreadWorker()
        {
            _callbackDoWorkEnd = new CallbackDoWorkEnd(DoWorkEnd);
        }
        public void Run()
        {
            DoWork();
            ThreadManager.Resume(_callbackDoWorkEnd);
        }
        public ThreadManager ThreadManager
        {
            get { return _threadManager; }
            set { _threadManager = value; }
        }
        public IThreadWorkerOption RunOption
        {
            get { return _runOption; }
            set { _runOption = value; }
        }
        private IThreadWorkerOption _runOption;
        private ThreadManager _threadManager;
    }
     
     
     
    如何使用:
    class Entry
    {
        public static void Main()
        {
            ThreadManager threadManager = new ThreadManager();
            threadManager.MaxThreadNum = 5;       
            for (int i=0; i<100; i++)
            {   
                IThreadWorkerOption runOption = new RunOption();
                ((RunOption)runOption).SleepTime = 5000;
                ((RunOption)runOption).ThreadNo = i;
                IThreadWorker worker = new Worker();
                threadManager.Run(worker, runOption);
                Console.WriteLine("Create, ThreadNum: " + threadManager.CurrentThreadNum);
            }
        }
    }
    class Worker : AbstractThreadWorker
    {
        public override void DoWork()
        {
            Thread.Sleep(((RunOption)RunOption).SleepTime);
        }
        public override void DoWorkEnd()
        {
            Console.WriteLine("Exit, ThreadNum: " + ThreadManager.CurrentThreadNum);
        }
    }
    class RunOption : IThreadWorkerOption
    {
        public RunOption()
        {
            SleepTime = 1000;
        }
        public int SleepTime
        {
            get { return _sleepTime; }
            set { _sleepTime = value; }
        }
        public int ThreadNo
        {
            get { return _threadNo; }
            set { _threadNo = value; }
        }
        private int _sleepTime;
        private int _threadNo;
       
    }
    6/5/2006

    Study MDX by example, lesson 4


    这部分内容是计算成员和命名集
    1.计算成员
    一般的作用就是对现有量度进行某种公式性的计算,形成新的量度
    先看个例子
    WITH
    MEMBER [Measures].[Avg Sales Price] AS
    ‘[Measures].[Dollar Sales] / [Measures].[Unit Sales]’
    SELECT
    { [Measures].[Dollar Sales], [Measures].[Unit Sales],
    [Measures].[Avg Sales Price]
    }
    on columns,
    { [Time].[Q1, 2005], [Time].[Q2, 2005] }
    on rows
    FROM Sales
    WHERE ([Customer].[MA])
     
    关键的部分是这个:
    WITH
    MEMBER [Measures].[Avg Sales Price] AS
    ‘[Measures].[Dollar Sales] / [Measures].[Unit Sales]’
    定义了一个叫[Avg Sales Price]的计算成员,然后在on columns中照常调用,很简单
     
    再看一个
    WITH
    MEMBER [Time].[Q1 to Q2 Growth] AS
    ‘[Time].[Q2, 2005] - [Time].[Q1, 2005]’
    包括一段时间,也就是说不一定非要是量度,维度也可以

    2.基本函数
    Avg(): Average (mean) of values
    Aggregate(): Aggregate of values based on server definition of aggregation function
    Count(): Count of values or tuples
    DistinctCount(): Distinct count of values or tuples
    Sum(): Sum of values
    Max(): Maximum of values
    Median(): Median value from a set
    Min(): Minimum of values
    NonEmptyCount(): Count of values or tuples Hyperion
    Stdev(): Sample standard deviation across values
    StdevP(): Population standard deviation across values
    Var(): Sample variance across values
    VarP(): Population variance
     
    如何使用:
    帅帅的标准差:
    语法是:Stdev (set [, numeric_value_expression])
    Stdev (
    [Product].[Tools].Children,
    [Measures].[Dollar Sales]
    )
    就是算[Product].[Tools].Children集合的[Measures].[Dollar Sales]值的标准差
     
    3.其它函数
    一些统计函数
    Correlation () Correlation coefficient of two data series over a set
    Covariance () Covariance of two data series over a set
    CovarianceN () (Microsoft) Sample covariance of two data series over a set
    LinRegIntercept () Linear regression intercept
    LinRegPoint () Point on linear regression line
    LinRegR2 () Linear regression coefficient
    LinRegSlope () Slope of linear regression line
    LinRegVariance () Variance of set from linear regression line
     
    一些数学函数
    Abs(num) Absolute value of num
    Exp(N) E raised to the power N
    Factorial(N) Factorial of N
    Int(num) Number rounded down to the next lowest integer
    Ln(num) Natural logarithm
    Log(num) Logarithm, base N
    Log10(num) Logarithm, base 10
    Mod(num, M) Modulus M (remainder from num divided by M)
    Power(num, M) Number num raised to power M
    Remainder(num) Number left over after removing integer portion from num
    Round(num, M) Number num rounded to M places
    Truncate(num) Number num with fractional part removed

    4.命名集
    命名集就是为维度集合起个别名呗
    先看个例子
    WITH SET [User Selection] AS
    ‘{ [Product].[Action Figures], [Product].[Dolls] }’
    MEMBER [Product].[UserTotal] AS
    ‘Sum ( [User Selection] )’
    SELECT
    { [Time].[Jan, 2005],
    [Time].[Feb, 2005]
    }
    ON COLUMNS,
    { [Product].[Toys],
    [User Selection],
    [Product].[UserTotal]
    }
    ON ROWS
    FROM Sales
    WHERE ([Measures].[Unit Sales])
     
    关键的部分:
    WITH SET [User Selection] AS
    ‘{ [Product].[Action Figures], [Product].[Dolls] }’

    下面计算成员调用了它
    MEMBER [Product].[UserTotal] AS
    ‘Sum ( [User Selection] )’

    5。命名集和计算成员混用:
    WITH
    SET [User Selection 1] AS ‘...’
    SET [User Selection 2] AS ‘...’
    MEMBER [Measures].[M1] AS ‘...’
    SET [User Selection 3] AS ‘...’
    MEMBER [Product].[P1] AS ‘...’
    6/1/2006

    Study MDX by example, lesson 3

    1.元组(Tuples)
    元组是一个或多个维度成员的集合,用()括起来,表示了cube的一个切片
    ([Customer].[Chicago, IL], [Time].[Jan, 2005])
    看个例子:
    SELECT
    { ( [Time].[2005], [Measures].[Dollar Sales] ),
    ( [Time].[Feb, 2005], [Measures].[Unit Sales] )
    }
    ON COLUMNS ,
    { [Product].[Tools], [Product].[Toys]} ON ROWS
    FROM [Sales]
    结果是:
     2005  Feb, 2005
     Dollar Sales Unit Sales
    Tools 1,083,855.90 2,621
    Toys 848,982.70 1,695
    挺难想象的
    当元组一旦把所有数据都集合起来那就是一个单元格了,比如:
    ([Product].[Leather Jackets], [Time].[June-2005],
    [Store].[Fifth Avenue NYC], [Measures].[Dollar Sales])
    它可能就是一个单元格的值
    空元组用(null) 或是 (null, null)

    2.集合(Sets)
    集合就是集合呗,用{}括起来
    我们经常看到这些的写法:{ ([Time].[Jun, 2005], [Geography].[Chicago, IL]) } on columns
    或者包含了几个元组:{ ( [Time].[2005], [Measures].[Dollar Sales] ),( [Measures].[Unit Sales], [Time].[Feb, 2005] )} on columns

    下面就将介绍一些元组和集合的基本操作
    3.CrossJoin()

    就是有点像笛卡你积的意思了
    写法:CrossJoin (set1, set2)
    比如
    CrossJoin (
    { [Time].[Q1, 2005], [Time].[Q2, 2005]},
    { [Measures].[Dollar Sales], [Measures].[Unit Sales] }
    )
    包含了四个切片:([Q1, 2005], [Dollar Sales])、([Q2, 2005], [Dollar Sales])、([Q1, 2005], [Unit Sales])、([Q2, 2005], [Unit Sales])
    完整的MDX写是:
    SELECT
    CrossJoin (
    { [Time].[Q1, 2005], [Time].[Q2, 2005]},
    { [Measures].[Dollar Sales], [Measures].[Unit Sales] }
    )
    ON COLUMNS ,
    { [Product].[Tools], [Product].[Toys] } ON ROWS
    FROM Sales
    可以想像的到,结果是有四列的
    实际上用*号也能完成同样的操作(看起来更清楚):
    { [Time].Members } * { [Scenario].Members } * { [Product].Members }
    CrossJoin甚至可以嵌套
    最后一个例子,和:号结合起来:
    CrossJoin (
    { [Product].[Toothpaste] },
    [Geography].[Store 1] : [Geography].[Store 10]
    )

    4.Filter()
    从集合中除去不满足条件的项目
    写法是:Filter (set, boolean-expression)
    比如:
    Filter (
    { [Product].[Product Category].Members },
    [Measures].[Dollar Sales] >= 500
    )
    意思是只包含满足条件[Dollar Sales] >= 500 的 [Product Category].Members

    5. Order()
    排序呗
    写法是:Order (set1, expression [, ASC | DESC | BASC | BDESC])
    SELECT
    { [Measures].[Dollar Sales] } on columns,
    Order (
    [Product].[Product Category].Members,
    [Measures].[Dollar Sales],
    BDESC
    )
    on rows
    FROM [Sales]
    WHERE [Time].[2004]
    将按Dollar Sales的大小排序
     

    Study MDX by example, lesson 2


    1. 逗号和冒号
    { [Time].[January 2005], [Time].[February 2005],
    [Time].[March 2005] }
    这个表达式选择了2005年前三个月,使用用了逗号分隔

    SELECT
    { [Time].[Sep,2004] : [Time].[Mar,2005] } on columns,
    { [Product].[Tools] : [Product].[Home Audio] } on rows
    FROM [Sales]
    WHERE ([Customer].[Lubbock, TX], [Measures].[Unit Sales])

    非常像excel:[Time].[Sep,2004] : [Time].[Mar,2005] ,就是选择了2004年9月到2005年3月这几个月

    逗号和冒号也可以混用,比如:
    { [Time].[2001], { [Time].[January-2001] : [Time].[March-2001] } }

     

    2 .Members
    SELECT
    { [Scenario].Members } on columns,
    { [Store].Members } on rows
    FROM Budgeting
    得显示Scenario和Store成员集合,但不显示计算成员(应调用.AllMembers)

     

    3 .Children和Descendants
    得到成员的儿子,和子孙(下钻操作)
    SELECT
    { [Time].[Q3, 2005].Children }
    on columns,
    { [Product].[Tools], [Product].[Tools].Children }
    on rows
    FROM Sales
    WHERE ([Customer].[TX], [Measures].[Unit Sales])

    [Time].[Q3, 2005].Children就包括:July, 2005 Aug, 2005 Sep, 2005

    得到子孙,使用Descendants (member [, [ level ] [, flag]] )
    其中flag包括
    SELF
    BEFORE
    AFTER
    SELF_AND_BEFORE
    SELF_AND_AFTER
    SELF_BEFORE_AFTER
    LEAVES

    SELECT
    { [Product].[Tools], [Product].[Toys] } ON COLUMNS,
    Descendants (
    [Time].[2005],
    [Time].[Month],
    SELF
    )
    ON ROWS
    FROM Sales
    WHERE [Measures].[Dollar Sales]

     

    4.移除空的切片
    使用NON EMPTY(切片就是cube一行或一列的数据啦)

    SELECT
    { [Time].[Jan, 2005], [Time].[Feb, 2005] }
    ON ROWS ,
    NON EMPTY
    { [Product].[Toys],
    [Product].[Toys].Children
    } ON COLUMNS
    FROM Sales
    WHERE [Customer].[TX]

    ROWS 返回的结果将不包含空行

     

    5。注释
    多行
    SELECT /* Put products
    on columns */ [Product].Members
    on columns FROM Cube

    单行
    SELECT // Put products on columns
    [Product].Members
    on columns FROM Cube

    SQL风格
    SELECT — Put products on columns
    [Product].Members
    on columns FROM Cube