| shuai's profile娱乐精神PhotosBlog | Help |
|
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 31.元组(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
SELECT 非常像excel:[Time].[Sep,2004] : [Time].[Mar,2005] ,就是选择了2004年9月到2005年3月这几个月 逗号和冒号也可以混用,比如:
2 .Members
3 .Children和Descendants [Time].[Q3, 2005].Children就包括:July, 2005 Aug, 2005 Sep, 2005 得到子孙,使用Descendants (member [, [ level ] [, flag]] ) SELECT
4.移除空的切片 SELECT ROWS 返回的结果将不包含空行
5。注释 单行 SQL风格 |
|
|