相关文章推荐
越狱的茶叶  ·  reportlab ...·  1 年前    · 
骑白马的红茶  ·  我用 JavaScript ...·  1 年前    · 
礼貌的木瓜  ·  wpf - C#.net - ...·  1 年前    · 

地方门户网站运营策略

很多经营地方门户网的站长看了我写的《想赚钱的个人网站站长要回答的33个问题》后与我交流,有些站长谈到经营地方门户网维护费劲,推广吃力,盈利困难,我不能和大家一一沟通,就写下这篇“浅谈如何运营地方门户网”和大家交流一下自己的看法。   首先,地方门户网站的站长要有“媒体”观念。   媒体是交流、传播信息的工具,是一种信息载体,如电视、广播、报刊杂志,互联网网络媒体被称为第四媒体。地方门户网的定位其实非常明确就是和地方电视台、地方报纸、地方广播一样是地方媒体。地方电视台、地方报纸、地方广播如何管理你就如何管理,地方电视台、地方报纸、地方广播如何推广你就如何推广,地方电视台、地方报纸、地方广播如何盈利你就如何盈利。当然你不要忘了网络媒体与传统媒体不一样的特点,不能看我这样说就完全生搬硬套,我这里说的意思是你要学习和掌握媒体运作的方式。   第二、地方门户网站的栏目设置首先要以便捷有效发布、查询各类地方群众需要的信息为主,不要贪大求全,更不要办成资讯网。   地方门户网是办给地方群众看的,满足地方群众需求了、地方群众登陆的多了,你的网站才会具有商业价值。地方群众上网查询最多的是房产信息、人才信息、婚介交友信息、二手信息、本地各类服务机构的电话信息、商户的促销信息等。地方新闻当然也是热门,但因为话题敏感,需要前置审批和采编困难,实力不够不建议做。地方门户网一般都设置有房产、人才等各类信息频道,但很多栏目都缺少便捷有效的分类检索功能,甚至有的网站信息栏目不是以信息为主,而是以资讯文章为主。要是看资讯文章大家就上新浪、搜狐了,到你这里干什么。栏目设置的多,精力自然就消耗的多,栏目质量就会降低。这也是很多地方门户网发展不过地方行业网的原因。   第三、地方门户网的推广要注意空地一体化推广,要擅长操作各种活动。   地方门户网的信息频道开始信息内容少怎么办,坐等网民发布当然不足取,有一个简单有效的方法介绍给大家,就是安排人手逐街逐巷的免费给当地商户和群众登记各类信息,免费发布到网上,每人每天指定信息登记任务量,然后汇总印刷成传单免费赠送,当然落款要打上自己的网址及广告词。边登记边宣传,对方想了解更多的信息时自然就会登陆你的网站,有些大爷大妈家里没有电脑,不会上网甚至会拿着传单到网吧找人帮助查找信息。这是个快捷有效的方法,成本只是1-2个人员的工资加上每张仅需几分钱的传单。   空是指网站,地是指地面活动,空地一体化指的是网站推广和现实活动相结合,有效的网站和地面活动相结合对于网站推广十分有利,比如与儿童影楼、幼儿园合作搞宝宝秀活动,与报社合作搞网上征文大赛,与妇联合作搞三八红旗手网上投票活动,与商家合作搞网上产品知识问答有奖比赛,还有什么城市小姐选拔、市花评选、书画展,摄影展、视频秀等等,各种活动你都可以参与,参与一个活动,影响一个群体,带来一批用户,发掘一批客户。当然每个活动都要考虑投入成本,尽量让要让合作单位或者赞助单位出钱,能盈利最好,不能盈利,也要达到我们的宣传目的。   第四、地方门户网要拓展信息采集渠道,搞好内容建设。   地方政府、地方电视台、地方广播、地方报纸、地方行业协会、地方信息中介公司等机构单位拥有自己的信息采集渠道,直接把他们采集的信息放到网上就是你的网站内容,可以考虑和这些机构单位合作,互惠互利,帮助他们实现内容网络化的同时也丰富了你的网站内容,但是和他们合作时一定要考虑到他们未来会不会独立运营把你甩掉,笔者认为一个好的方法就是,他们如果未来适合独立运营并且很有独立运营意向,那么就让他们启用独立域名,你赚取他们的域名空间和系统开发、内容维护费用,把他变成你的客户。同时考虑到地方门户行业未来必然持续加大竞争,你如果能制定合理的频道投入、推广和利润分配机制,让他们先行投入、发展后盈利,成为你的频道合作伙伴,会使你赢得未来竞争的优势。   第五、地方门户网的系统如果自己没有精力和实力持续开发和升级,就不如选购地方门户网程序专业开发者的产品。   地方门户网的持续开发是个极其消耗精力的过程,设置什么频道、增加什么功能、如何做到操作人性化、如何设计盈利模式,等你想好了、开发好了也许机会就丧失了。因此选择有实力的、专一的、持续升级的、行业中数一数二的地方门户网专业程序开发商的系统是个比较好的选择。当然还要考虑程序开发者的项目策划和推广能力,纯粹从程序员的角度构思开发的系统未必能适合市场的需要。要是有专业的地方门户网开发者认为自己开发的系统不错,可以与我联系,我来协助大家挑选。   第六、地方门户网的运营一定要考虑投资回报周期问题。   有很多地方门户网有着很好的规划,但是盈利缓慢,运营1-2年后都没有很好的效益,就会丧失经营的兴趣,减少投入。尤其是个人站长运营地方门户一定要计算你的网站月度最低要开支多少、多少时间后收支平衡,多长时间后能盈利,多长时间后纯利润达到你的目标收入,你是否有足够的资金撑到达到盈利目标的哪一天?要知道这个行业随时随地会诞生出很多竞争对手,你如果不能快速实现盈利目标,你就没有足够的实力支撑你持续发展。   第七、地方门户网的盈利模式问题。   地方门户网常见的盈利模式有商户加盟费,商家联合优惠会员卡销售收入、页面广告费、广告联盟收入、VIP会员费、频道冠名收入等,这些形式大家都知道,那我们应该采用哪种盈利模式呢?我个人认为关键是看你的优势何在,你有能力先掌握商户资源还是普通用户资源,有能力掌握信息资源还是广告资源。你必须先获得一块资源才能利用这块资源吸引需求方,然后获得利润。比如,你能先发展了大量的网站会员,你就可以向商家收取加盟费和广告费;你能先联合大量商家加盟,你就可以销售联合优惠卡;你要是能获得第一手的准确信息,你就可以收取VIP会员费;你要是擅长规划和推广,你就可以赚到频道冠名费;你要是能力突出,你还可以赚到合作推广赞助费。采用哪种盈利模式没有定式,关键要看你的资源优势何在、看市场发展历程、看竞争对手的策略,法无定法、适合为上。   第八、地方门户网的发展和前景问题   地方门户网是地方媒体的有效组成部分,有其合理存在的意义,只要认真调研、合理规划、精心操作、持续发展必然能在地方媒体中获得一席之地,一个地级城市发展好了一年少则十几万、多则几十万的收入应该是合理的。但是未来地方门户网的竞争也必然是无比惨烈的,各大网站的分站连锁加盟,地方媒体的强势介入,新公司新人的不断进入及互联网发展的不断创新变化,这个行业不是容易做的,但风险与机会并存,任何一个地方门户网站如果能注重客户体验,持续开发并探索总结出有效的推广套路,必然也能获得一个发展机遇。除实力之外,发展无捷径,看谁更专一专注而已。有心经营地方门户网的朋友可以登陆小站妙创网对照敝作“想赚钱的个人网站站长要回答的33个问题”作出自己的规划。 分类: 其它 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/3624001.html,如需转载请自行联系原作者

asp.net发布到IIS中出现错误:处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler”

开发web项目时需要安装IIS,在安装好IIS的Windows7本上发布asp.net网站时,web程序已经映射到了本地IIS上,但运行如下错误提示“处理程序“PageHandlerFactory-Integrated”在其模块列表中有一个错误模块“ManagedPipelineHandler””  我要发布的的web项目开发工具及所用系统 ①开发工具:vs2010、数据库:sqlserver ②操作系统:windows7 ③IIS:IIS 7.5 一.上述错误详情图: 二.上述错误分析: vs2010默认采用的是.NET 4.0框架,4.0框架是独立的CLR,和.NET 2.0的不同,如果想运行.NET 4.0框架的网站,需要用aspnet_regiis注册.NET 4.0框架,然后用.NET 4.0框架的class池,就可以运行.NET 4.0框架的web项目了。 造成上述错误的原因极有可能是:由于先安装.NetFramework v4.0后安装iis 7.5所致。 三.如何用aspnet_regiis注册4.0框架?    方法如下: ①找到.NET 4.0框架下aspnet_regiis所在目录,在C盘根目录中搜索aspnet_regiis,找到4.0框架下aspnet_regiis的目录位置,本人本本目录为"C:\Windows\Microsoft.NET\Framework\v4.0.30319". #数据类型一:条目(用户、商品、打分)(避免巨型稀疏矩阵) csv_txt = '''"Angelica","Blues Traveler",3.5 "Angelica","Broken Bells",2.0 "Angelica","Norah Jones",4.5 "Angelica","Phoenix",5.0 "Angelica","Slightly Stoopid",1.5 "Angelica","The Strokes",2.5 "Angelica","Vampire Weekend",2.0 "Bill","Blues Traveler",2.0 "Bill","Broken Bells",3.5 "Bill","Deadmau5",4.0 "Bill","Phoenix",2.0 "Bill","Slightly Stoopid",3.5 "Bill","Vampire Weekend",3.0 "Chan","Blues Traveler",5.0 "Chan","Broken Bells",1.0 "Chan","Deadmau5",1.0 "Chan","Norah Jones",3.0 "Chan","Phoenix",5, "Chan","Slightly Stoopid",1.0 "Dan","Blues Traveler",3.0 "Dan","Broken Bells",4.0 "Dan","Deadmau5",4.5 "Dan","Phoenix",3.0 "Dan","Slightly Stoopid",4.5 "Dan","The Strokes",4.0 "Dan","Vampire Weekend",2.0 "Hailey","Broken Bells",4.0 "Hailey","Deadmau5",1.0 "Hailey","Norah Jones",4.0 "Hailey","The Strokes",4.0 "Hailey","Vampire Weekend",1.0 "Jordyn","Broken Bells",4.5 "Jordyn","Deadmau5",4.0 "Jordyn","Norah Jones",5.0 "Jordyn","Phoenix",5.0 "Jordyn","Slightly Stoopid",4.5 "Jordyn","The Strokes",4.0 "Jordyn","Vampire Weekend",4.0 "Sam","Blues Traveler",5.0 "Sam","Broken Bells",2.0 "Sam","Norah Jones",3.0 "Sam","Phoenix",5.0 "Sam","Slightly Stoopid",4.0 "Sam","The Strokes",5.0 "Veronica","Blues Traveler",3.0 "Veronica","Norah Jones",5.0 "Veronica","Phoenix",4.0 "Veronica","Slightly Stoopid",2.5 "Veronica","The Strokes",3.0''' #数据类型二:json数据(用户、商品、打分) json_txt = '''{"Angelica": {"Blues Traveler": 3.5, "Broken Bells": 2.0, "Norah Jones": 4.5, "Phoenix": 5.0, "Slightly Stoopid": 1.5, "The Strokes": 2.5, "Vampire Weekend": 2.0}, "Bill":{"Blues Traveler": 2.0, "Broken Bells": 3.5, "Deadmau5": 4.0, "Phoenix": 2.0, "Slightly Stoopid": 3.5, "Vampire Weekend": 3.0}, "Chan": {"Blues Traveler": 5.0, "Broken Bells": 1.0, "Deadmau5": 1.0, "Norah Jones": 3.0, "Phoenix": 5, "Slightly Stoopid": 1.0}, "Dan": {"Blues Traveler": 3.0, "Broken Bells": 4.0, "Deadmau5": 4.5, "Phoenix": 3.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 2.0}, "Hailey": {"Broken Bells": 4.0, "Deadmau5": 1.0, "Norah Jones": 4.0, "The Strokes": 4.0, "Vampire Weekend": 1.0}, "Jordyn": {"Broken Bells": 4.5, "Deadmau5": 4.0, "Norah Jones": 5.0, "Phoenix": 5.0, "Slightly Stoopid": 4.5, "The Strokes": 4.0, "Vampire Weekend": 4.0}, "Sam": {"Blues Traveler": 5.0, "Broken Bells": 2.0, "Norah Jones": 3.0, "Phoenix": 5.0, "Slightly Stoopid": 4.0, "The Strokes": 5.0}, "Veronica": {"Blues Traveler": 3.0, "Norah Jones": 5.0, "Phoenix": 4.0, "Slightly Stoopid": 2.5, "The Strokes": 3.0} df = None #方式一:加载csv数据 def load_csv_txt(): global df df = pd.read_csv(StringIO(csv_txt), header=None, names=['user','goods','rate']) #方式二:加载json数据(把json读成条目) def load_json_txt(): global df #由json数据得到字典 users = json.loads(json_txt) #遍历字典,得到条目 csv_txt_ = '' for user in users: for goods in users[user]: csv_txt_ += '{},{},{}\n'.format(user, goods, users[user][goods]) df = pd.read_csv(StringIO(csv_txt_), header=None, names=['user','goods','rate']) print('测试:读取数据') #load_csv_txt() load_json_txt() def build_xy(user_name1, user_name2): df1 = df.ix[df['user'] == user_name1, ['goods','rate']] df2 = df.ix[df['user'] == user_name2, ['goods','rate']] df3 = pd.merge(df1, df2, on='goods', how='inner') #只保留两人都有评分的商品的评分 return df3['rate_x'], df3['rate_y'] #merge之后默认的列名:rate_x,rate_y def manhattan(user_name1, user_name2): x, y = build_xy(user_name1, user_name2) return sum(abs(x - y)) #欧几里德距离 def euclidean(user_name1, user_name2): x, y = build_xy(user_name1, user_name2) return sum((x - y)**2)**0.5 #闵可夫斯基距离 def minkowski(user_name1, user_name2, r): x, y = build_xy(user_name1, user_name2) return sum(abs(x - y)**r)**(1/r) #皮尔逊相关系数 def pearson(user_name1, user_name2): x, y = build_xy(user_name1, user_name2) mean1, mean2 = x.mean(), y.mean() denominator = (sum((x-mean1)**2)*sum((y-mean2)**2))**0.5 return [sum((x-mean1)*(y-mean2))/denominator, 0][denominator == 0] #余弦相似度(数据的稀疏性问题,在文本挖掘中应用得较多) def cosine(user_name1, user_name2): x, y = build_xy(user_name1, user_name2) denominator = (sum(x*x)*sum(y*y))**0.5 return [sum(x*y)/denominator, 0][denominator == 0] metric_funcs = { 'manhattan': manhattan, 'euclidean': euclidean, 'minkowski': minkowski, 'pearson': pearson, 'cosine': cosine print('\n测试:计算Angelica与Bill的曼哈顿距离') print(manhattan('Angelica','Bill')) #计算最近的邻居(返回:pd.Series) def computeNearestNeighbor(user_name, metric='pearson', k=3, r=2): metric: 度量函数 k: 返回k个邻居 r: 闵可夫斯基距离专用 返回:pd.Series,其中index是邻居名称,values是距离 array = df[df['user'] != user_name]['user'].unique() if metric in ['manhattan', 'euclidean']: return pd.Series(array, index=array.tolist()).apply(metric_funcs[metric], args=(user_name,)).nsmallest(k) elif metric in ['minkowski']: return pd.Series(array, index=array.tolist()).apply(metric_funcs[metric], args=(user_name, r,)).nsmallest(k) elif metric in ['pearson', 'cosine']: return pd.Series(array, index=array.tolist()).apply(metric_funcs[metric], args=(user_name,)).nlargest(k) print('\n测试:计算Hailey的最近邻居') print(computeNearestNeighbor('Hailey')) #向给定用户推荐(返回:pd.DataFrame) def recommend(user_name): """返回推荐结果列表""" # 找到距离最近的用户名 nearest_username = computeNearestNeighbor(user_name).index[0] # 找出这位用户评价过、但自己未曾评价的乐队 df1 = df.ix[df['user'] == user_name, ['goods', 'rate']] df2 = df.ix[df['user'] == nearest_username, ['goods', 'rate']] df3 = pd.merge(df1, df2, on='goods', how='outer') return df3.ix[(df3['rate_x'].isnull()) & (df3['rate_y'].notnull()), ['goods', 'rate_y']].sort_values(by='rate_y') print('\n测试:为Hailey做推荐') print(recommend('Hailey')) #向给定用户推荐(返回:pd.Series) def recommend2(user_name, metric='pearson', k=3, n=5, r=2): metric: 度量函数 k: 根据k个最近邻居,协同推荐 r: 闵可夫斯基距离专用 n: 推荐的商品数目 返回:pd.Series,其中index是商品名称,values是加权评分 # 找到距离最近的k个邻居 nearest_neighbors = computeNearestNeighbor(user_name, metric='pearson', k=k, r=r) # 计算权值 if metric in ['manhattan', 'euclidean', 'minkowski']: # 距离越小,越类似 nearest_neighbors = 1 / nearest_neighbors # 所以,取倒数(或者别的减函数,如:y=2**-x) elif metric in ['pearson', 'cosine']: # 距离越大,越类似 nearest_neighbors = nearest_neighbors / nearest_neighbors.sum() #已经变为权值 # 逐个邻居找出其评价过、但自己未曾评价的乐队(或商品)的评分,并乘以权值 neighbors_rate_with_weight = [] for neighbor_name in nearest_neighbors.index: # 每个结果:pd.Series,其中index是商品名称,values是评分(已乘权值) df1 = df.ix[df['user'] == user_name, ['goods', 'rate']] df2 = df.ix[df['user'] == neighbor_name, ['goods', 'rate']] df3 = pd.merge(df1, df2, on='goods', how='outer') df4 = df3.ix[(df3['rate_x'].isnull()) & (df3['rate_y'].notnull()), ['goods', 'rate_y']] #注意这中间有一个转化为pd.Series的操作! neighbors_rate_with_weight.append(pd.Series(df4['rate_y'].tolist(), index=df4['goods']) * nearest_neighbors[neighbor_name]) # 把邻居们的加权评分拼接成pd.DataFrame,按列累加,取最大的前n个商品的评分 return pd.concat(neighbors_rate_with_weight, axis=1).sum(axis=1, skipna=True).nlargest(n) # 黑科技! print('\n测试:为Hailey做推荐') print(recommend2('Hailey', metric='manhattan', k=3, n=5)) print('\n测试:为Hailey做推荐') print(recommend2('Hailey', metric='euclidean', k=3, n=5, r=2)) print('\n测试:为Hailey做推荐') print(recommend2('Hailey', metric='pearson', k=1, n=5))

git push上传代码到gitlab上,报错401/403(或需要输入用户名和密码)

之前部署的gitlab,采用ssh方式连接gitlab,在客户机上产生公钥上传到gitlab的SSH-Keys里,git clone下载和git push上传都没问题,这种方式很安全。 后来应开发同事要求采用http方式连接gitlab,那么首先将project工程的“Visibility Level”改为“Public”公开模式,要保证gitlab的http端口已对客户机开放。 后面发现了一个问题:http方式连接gitlab后,git clone下载没有问题,但是git push上传有报错:error: The requested URL returned error: 401 Unauthorized while accessing http://git.xqshijie.net:8081/weixin/weixin.git/info/refsfatal: HTTP request failed 或者The requested URL returned error: 403 Forbidden while accessing 实例如下:假设git的url为http://git.wangshibo.net [root@test-huanqiu ~]# mkdir /root/git [root@test-huanqiu ~]# cd /root/git [root@test-huanqiu git]# git init . [root@test-huanqiu git]# git clone http://git.wangshibo.net:8081/weixin/weixin.git Initialized empty Git repository in /root/git/weixin/.git/ remote: Counting objects: 10, done. remote: Compressing objects: 100% (6/6), done. remote: Total 10 (delta 0), reused 0 (delta 0) Unpacking objects: 100% (10/10), done. 上面可以看出,已经能成功git clone下代码 [root@test-huanqiu git]# ll total 4 drwxr-xr-x. 3 root root 4096 Nov 30 15:58 weixin [root@test-huanqiu git]# cd weixin/ [root@test-huanqiu weixin]# ll total 8 -rw-r--r--. 1 root root 15 Nov 30 15:58 heihei -rw-r--r--. 1 root root 1 Nov 30 15:38 README.md 现在测试下git push [root@test-huanqiu weixin]# git rm heihei [root@test-huanqiu weixin]# touch test.file [root@test-huanqiu weixin]# echo "123456" > test.file [root@test-huanqiu weixin]# git add . [root@test-huanqiu weixin]# git commit -m "this is a test" [root@test-huanqiu weixin]# git push                                      //或者git push -u origin mastererror: The requested URL returned error: 401 Unauthorized while accessing http://git.wangshibo.net:8081/weixin/weixin.git/info/refs fatal: HTTP request failed 解决办法:在代码的.git/config文件内[remote "origin"]的url的gitlab域名前添加gitlab注册时的“用户名:密码@”另外发现这个用户要在对应项目下的角色是Owner或Master才行,如果是Guest、Reporter、Developer,则如下操作后也是不行。 如下,gitlab的用户名是wangshibo,假设密码是HU@wew12378!h8 查看gitlab界面里的登陆用户名: 然后修改代码里的.git/config文件 [root@test-huanqiu weixin]# cd .git [root@test-huanqiu .git]# cat config  [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = http://git.wangshibo.net:8081/weixin/weixin.git [branch "master"] remote = origin merge = refs/heads/master修改如下: [root@test-huanqiu .git]# cat config  [core] repositoryformatversion = 0 filemode = true bare = false logallrefupdates = true [remote "origin"] fetch = +refs/heads/*:refs/remotes/origin/* url = http://wangshibo:HU@wew12378!h8@git.wangshibo.net:8081/weixin/weixin.git [branch "master"] remote = origin merge = refs/heads/master 然后再次git push,发现可以正常提交了! [root@test-huanqiu weixin]# git push Counting objects: 4, done. Delta compression using up to 8 threads. Compressing objects: 100% (2/2), done. Writing objects: 100% (3/3), 297 bytes, done. Total 3 (delta 0), reused 0 (delta 0) To http://wangshibo:HUIhui1987521@git.xqshijie.net:8081/weixin/weixin.git 8fcb559..6c97b56 master -> master ------------------------------------------------------------------------------------------------------------------------------------ 可以创建一个用户名作为admin管理员,然后将这个用户名和密码添加到项目代码的.git/config里面,如上操作! 如果不是管理员,则至少对当前代码具有owner或master权限。 这样,在.git/config文件里添加这个用户名和密码权限,然后其他人在git push的时时候都使用这个文件进行覆盖。 其他人在首次git clone下载代码的时候,需要进行--global全局配置,然后就可以在gitweb控制台里追踪到每个操作者的提交记录了! ***************当你发现自己的才华撑不起野心时,就请安静下来学习吧*************** 本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/6118297.html,如需转载请自行联系原作者

Android核心分析28篇,强烈推荐android初学者,android进阶者看看这个系列教程

为什么要研究Android,是因为它够庞大,它够复杂,他激起了我作为一个程序员的内心的渴望,渴望理解这种复杂性。我研究的对象是作为手机开发平台的Android软件系统部分,而不是Dalvik虚拟机本身。  作为一个从其他平台装接过来的程序员,要从事Andoid平台系统开发,我的关于手机平台上积累的知识已经不能满足需要了,Android为我们带来了大量的新名词,Activity,Manifest,INTENT,Service,Binder,Dalvik虚拟机,Framework,Linux,Navtive ,JNI.....。通过在源代码,在开发社区,在开发博客,甚至在招聘过程中,我不断的寻求Android是什么。经过一定时间的沉淀,我慢慢的理解到Android不仅仅是一类手机的总称,不仅仅是一个手机开发平台,不仅仅是一个虚拟java操作系统,不仅仅是一个开发社区,一个开发标准,不仅仅是一堆代码,Android已经成了一个新的潮流。 <ignore_js_op> Android核心分析 之一分析方法论探讨之设计意图http://www.apkbus.com/android-24212-1-1.htmlAndroid核心分析 之二方法论探讨之概念空间篇http://www.apkbus.com/android-24213-1-1.htmlAndroid是什么 之三手机之硬件形态http://www.apkbus.com/android-24215-1-2.html Android核心分析之四手机的软件形态http://www.apkbus.com/android-24216-1-1.htmlAndroid 核心分析 之五基本空间划分http://www.apkbus.com/android-24217-1-1.htmlAndroid 核心分析 之六 IPC框架分析 Binder,Service,Service managerhttp://www.apkbus.com/android-24218-1-1.htmlAndroid 核心分析 之七ervice深入分析http://www.apkbus.com/android-24219-1-1.htmlAndroid 核心分析 之八Android 启动过程详解http://www.apkbus.com/android-24220-1-1.htmlAndroid核心分析 之九Zygote Servicehttp://www.apkbus.com/android-24245-1-1.htmlAndroid核心分析 之十Android GWES之基本原理篇http://www.apkbus.com/android-24221-1-1.htmlAndroid核心分析 之十一Android GWES之消息系统http://www.apkbus.com/android-24222-1-1.htmlAndroid 核心分析之十二Android GEWS窗口管理之基本架构原理http://www.apkbus.com/android-24223-1-1.htmlAndroid 核心分析之十三Android GWES之Android窗口管理http://www.apkbus.com/android-24224-1-1.htmlAndroid核心分析之十四Android GWES之输入系统http://www.apkbus.com/android-24225-1-1.htmlAndroid核心分析之十五Android输入系统之输入路径详解http://www.apkbus.com/android-24226-1-1.htmlAndroid核心分析之十六Android电话系统-概述篇http://www.apkbus.com/android-24227-1-1.htmlAndroid核心分析之十七电话系统之rilDhttp://www.apkbus.com/android-24228-1-1.htmlAndroid核心分析之十八Android电话系统之RIL-Javahttp://www.apkbus.com/android-24229-1-1.htmlAndroid核心分析之十九电话系统之GSMCallTackerhttp://www.apkbus.com/android-24230-1-1.htmlAndroid核心分析之二十Android应用程序框架之无边界设计意图http://www.apkbus.com/android-24231-1-1.htmlAndroid核心分析之二十一Android应用框架之AndroidApplicationhttp://www.apkbus.com/android-24232-1-1.htmlAndroid核心分析之二十二Android应用框架之Activityhttp://www.apkbus.com/android-24233-1-1.htmlAndroid核心分析之二十三Andoird GDI之基本原理及其总体框架http://www.apkbus.com/android-24236-1-1.htmlAndroid核心分析之二十四Android GDI之显示缓冲管理http://www.apkbus.com/android-24237-1-1.htmlAndroid核心分析之二十五Android GDI之共享缓冲区机制http://www.apkbus.com/android-24238-1-1.htmlAndroid核心分析之二十六Android GDI之SurfaceFlingerhttp://www.apkbus.com/android-24239-1-1.htmlAndroid核心分析之二十七Android GDI 之SurfaceFlinger之动态结构示意图http://www.apkbus.com/android-24240-1-1.htmlAndroid核心分析之二十八Android GDI之Surface&Canvashttp://www.apkbus.com/android-24242-1-1.html如果觉得好的话,就一定不要忘了分享哦!!

iOS:使用Github托管自己本地的项目代码方式一:(Xcode方式:开发工具Xcode配置Git,由Xcode-->Source Control-->Commit)

管理代码的地方主要有:Github(国外流行)、CocoaChina、Cocoa4App、中国开源社区、CSDN、博客园、简书等等、、、、、 现在主要介绍如何使用Github托管自己的项目代码。 尊重原创,特地说明接下面的介绍转载自简书:http://www.jianshu.com/p/f3cba0a3f1bd 注意: 此教程只针对iOS项目,其他项目请参考此网站 http://jingyan.baidu.com/article/b907e627aadbb246e7891cf1.html 1.首先进入github官网注册一个帐号 2.注册完账号之后创建一个项目 3.设置创建项目的信息 4.创建项目完之后复制项目的地址,以供后面下载项目使用 之前地址位置: 现在地址位置:这是我创建项目后显示的地址 5.在桌面创建一个文件夹,用来存储项目并进行管理 6.打开终端,按照步骤输入指令,下载速度可能很慢,要保证你的网速够快,毕竟是外网. 7.下载成功之后打开文件夹会发现有.gitignore readme 文件,就代表可以使用Xcode创建项目了 8.下面使用xcode创建项目 9.创建项目成功之后 10.此时可以先提交项目 11.提交项目所要输入的说明, 如果仅仅是上传自己的项目就勾选push ,push是将本地服务器的代码上传到远程服务器 12.输入Github的账号和密码 13.进入github网站,刷新一下界面,你就会发现成功了! 然后就可以在项目中尽情写自己的代码了. 写完代码继续提交项目就可以了

使用JQuery操作cookie时 发生取的值不正确,结果发现cookie有四个不同的属性,分享下错误的原因及解决方法。 使用JQuery操作cookie时 发生取的值不正确的问题:  结果发现cookie有四个不同的属性:  名称,内容,域,路径  $.cookie('the_cookie'); // 读取 cookie $.cookie('the_cookie', 'the_value'); // 存储 cookie $.cookie('the_cookie', 'the_value', { expires: 7 }); // 存储一个带7天期限的 cookie $.cookie('the_cookie', '', { expires: -1 }); // 删除 cookie  $.cookie("currentMenuID", menuID); 时 未指定域和路径。  所有当域和路径不同时会产生不同的cookie  $.cookie("currentMenuID"); 取值时会产生问题。  $.cookie("currentMenuID", "menuID", { path: "/"});  进行覆盖。同域下同一个cookieID对应一个值。 分类: Jquery 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/3336484.html,如需转载请自行联系原作者

ajax中加上AntiForgeryToken防止CSRF攻击

经常看到在项目中ajax post数据到服务器不加防伪标记,造成CSRF攻击 在Asp.net Mvc里加入防伪标记很简单在表单中加入Html.AntiForgeryToken()即可。 Html.AntiForgeryToken()会生成一对加密的字符串,分别存放在Cookies 和 input 中。 我们在ajax post中也带上AntiForgeryToken <h4>Persen</h4> <hr /> @Html.ValidationSummary(true, "", new { @class = "text-danger" }) <div class="form-group"> @Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> @Html.LabelFor(model => model.Age, htmlAttributes: new { @class = "control-label col-md-2" }) <div class="col-md-10"> @Html.EditorFor(model => model.Age, new { htmlAttributes = new { @class = "form-control" } }) @Html.ValidationMessageFor(model => model.Age, "", new { @class = "text-danger" }) </div> </div> <div class="form-group"> <div class="col-md-offset-2 col-md-10"> <input type="button" id="save" value="Create" class="btn btn-default" /> </div> </div> </div> </form> <script src="~/Scripts/jquery-1.10.2.min.js"></script> <script src="~/Scripts/jquery.validate.min.js"></script> <script src="~/Scripts/jquery.validate.unobtrusive.min.js"></script> <script type="text/javascript"> $(function () { //var token = $('[name=__RequestVerificationToken]'); //获取防伪标记 var token = $('@Html.AntiForgeryToken()').val(); var headers = {}; //防伪标记放入headers //也可以将防伪标记放入data headers["__RequestVerificationToken"] = token; $("#save").click(function () { $.ajax({ type: 'POST', url: '/Home/Index', cache: false, headers: headers, data: { Name: "yangwen", Age: "1" }, success: function (data) { alert(data) error: function () { alert("Error") </script> public class MyValidateAntiForgeryToken : AuthorizeAttribute public override void OnAuthorization(AuthorizationContext filterContext) var request = filterContext.HttpContext.Request; if (request.HttpMethod == WebRequestMethods.Http.Post) if (request.IsAjaxRequest()) var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName]; var cookieValue = antiForgeryCookie != null ? antiForgeryCookie.Value : null; //从cookies 和 Headers 中 验证防伪标记 //这里可以加try-catch AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]); new ValidateAntiForgeryTokenAttribute() .OnAuthorization(filterContext); //var token = $('[name=__RequestVerificationToken]'); //获取防伪标记 var token = $('@Html.AntiForgeryToken()').val(); var headers = {}; //防伪标记放入headers //也可以将防伪标记放入data headers["__RequestVerificationToken"] = token+11111111111111111111111111111111111; $("#save").click(function () { $.ajax({ type: 'POST', url: '/Home/Index', cache: false, headers: headers, data: { Name: "yangwen", Age: "1" }, success: function (data) { alert(data) error: function () { alert("Error")             Console.WriteLine("请输入最大数n");             int n = Convert.ToInt32(Console.ReadLine());             Console.WriteLine(sum(n));         private static int sum(int n)             int nsum;             if (n == 1)                  nsum = 1;             nsum = n * n + sum(n - 1);         return             nsum;

WCF BasicHttpBinding 安全解析(6)Digest验证(IIS宿主)

Digest验证方式在Basic验证方式的基础上增加了摘要信息,采用的是挑战-应答模式。Digest验证也是Http安全验证的标准(RFC 2617)。 首先我们修改服务端配置文件启用Digest验证,如代码清单11-95。 代码清单11-95 启用Digest验证 <basicHttpBinding><binding name="basicBindingConf"><security mode="TransportCredentialOnly"><transport clientCredentialType="Digest"></transport></security></binding></basicHttpBinding> 同样,我们需要配置IIS启用摘要式身份验证,然后更新测试站点的服务引用。 默认情况下是不需要显示传递用户名和密码等信息给服务端的,如果想要传递该信息可以使用代码清单11-96的方式。 代码清单11-96 摘要验证方式显示传递身份信息 p.ClientCredentials.HttpDigest.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Impersonation; p.ClientCredentials.HttpDigest.ClientCredential =new System.Net.NetworkCredential("v-samzha","domain_pwd"); 如代码清单11-96,摘要验证的身份信息保存在p.ClientCredentials.HttpDigest对象中。 下面我们分析一下摘要验证的过程。 先看代码清单11-97是第发起请求的信息。 代码清单11-97 发起请求 POST http://wcfservicewebsite.com/HelloService.svc HTTP/1.1 Content-Type: text/xml; charset=utf-8 VsDebuggerCausalityData: uIDPo9ymOexINPFJi+3tKDrHjuIAAAAAGYVyeTYe3UqAVZgCC45FRE5qbQJALydCjORFK5/dBBoACQAA SOAPAction: "http://tempuri.org/IHelloService/GetHello" Host: wcfservicewebsite.com Content-Length: 133 Expect: 100-continue Accept-Encoding: gzip, deflate Connection: Keep-Alive <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetHello xmlns="http://tempuri.org/"/></s:Body></s:Envelope> 从代码清单11-97,我们可以看出第一次请求没有提供任何验证信息,肯定是不能通过验证的,那么服务端返回的信息是什么呢?看代码清单11-98。 代码清单11-98 第一次请求失败的服务端信息 HTTP/1.1 401 Unauthorized Cache-Control: private Content-Type: text/html; charset=utf-8 Server: Microsoft-IIS/7.5 WWW-Authenticate: Digest qop="auth",algorithm=MD5-sess,nonce="+Upgraded+v1b410f2cc9b3070af323f9066253e36c8cf176bcec933cc01c4ff7612615bd9d42b1607c3e122bcba7ca83f47d02c6f1169f78240641df79c",charset=utf-8,realm=" bs--yangwenhai" X-Powered-By: ASP.NET Date: Sun, 26 Jun 2011 06:25:13 GMT Content-Length: 6079 服务端的返回信息中,我们关注代码清单11-98中加粗的部分,它告诉客户端验证方式为Digest,采用的摘要的算法为MD5-sess。qop表示用于服务器回应的保护等级选项,"auth"值表示鉴别;而"auth-int"值则表示采用完整性保护的鉴别。nonce字段是服务器返回的标识,每次请求都不一样,使用如下生产规则: time-stamp H(time-stamp ":" ETag ":" private-key) H为采用的摘要算法。 realm=" bs--yangwenhai"声明当前验证的域为bs--yangwenhai。 客户端接收到这样的反馈之后,会发送Digest验证信息给服务端,如代码清单11-99。 代码清单11-99 客户端发送Digest验证信息 POST http://wcfservicewebsite.com/HelloService.svc HTTP/1.1 Content-Type: text/xml; charset=utf-8 VsDebuggerCausalityData: uIDPo9ymOexINPFJi+3tKDrHjuIAAAAAGYVyeTYe3UqAVZgCC45FRE5qbQJALydCjORFK5/dBBoACQAA SOAPAction: "http://tempuri.org/IHelloService/GetHello" Accept-Encoding: gzip, deflate,gzip, deflate Authorization: Digest username="administrator",realm="bs--yangwenhai",nonce="+Upgraded+v1b410f2cc9b3070af323f9066253e36c8cf176bcec933cc01c4ff7612615bd9d42b1607c3e122bcba7ca83f47d02c6f1169f78240641df79c",uri="http://wcfservicewebsite.com/HelloService.svc",cnonce="+Upgraded+v1462dbb5533a1c4c04d59d91a9b10460cfd38ba314128516a4b17391abdc5a273",nc=00000001,algorithm=MD5-sess,response="9aefaca8ec6d904bb0bc43f068e328e2",qop="auth",charset=utf-8,hashed-dirs="service-name,channel-binding",service-name="HTTP/wcfservicewebsite.com",channel-binding="00000000000000000000000000000000" Host: wcfservicewebsite.com Content-Length: 133 Expect: 100-continue <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"><s:Body><GetHello xmlns="http://tempuri.org/"/></s:Body></s:Envelope> 代码清单11-99是客户端发送的验证信息,其中nonce值与服务端返回的值相同,客户端将密码经过Md5加密放在头部传回服务端。服务端接受到该请求之后,从header中提取有效的client credential,并通过LDAP服务,连接至DC,查找相应用户名与摘要信息匹配的domain user。如果找到,说明该 credential有效,则开始处理请求,否则,返回401给客户端。 本文转自悬魂博客园博客,原文链接:http://www.cnblogs.com/xuanhun/archive/2011/07/01/2095553.html,如需转载请自行联系原作者

/// </summary> /// <param name="e">传入枚举对象</param> /// <returns>得到对应描述信息</returns> public String GetEnumDesc(Enum e) FieldInfo EnumInfo = e.GetType().GetField(e.ToString()); if (EnumInfo == null) return ""; DescriptionAttribute[] EnumAttributes = (DescriptionAttribute[])EnumInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (EnumAttributes.Length > 0) return EnumAttributes[0].Description; return e.ToString(); /// <summary> /// 将含有描述信息的枚举绑定到列表控件中 /// </summary> /// <param name="listControl"></param> /// <param name="enumType"></param> private Dictionary<string, string> BindDesEnumToListControl(System.Type enumType) Dictionary<string, string> dic = new Dictionary<string, string>(); foreach (object enumValue in Enum.GetValues(enumType)) Enum e = (Enum)enumValue; dic.Add(((int)enumValue).ToString(), GetEnumDesc(e)); return dic; 还有一个是根据传入的枚举的数字索引直接获取 public static string GetEnumDesc<T>(Object obj) obj = (T)obj; if (obj == null) throw new ArgumentNullException("参数不能为null"); if (!obj.GetType().IsEnum) throw new Exception("参数类型不正确"); FieldInfo fieldinfo = obj.GetType().GetField(obj.ToString()); string str = string.Empty; Object[] objs = fieldinfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (objs != null && objs.Length != 0) DescriptionAttribute des = (DescriptionAttribute)objs[0]; str = des.Description; return str;

Oracle日常运维操作总结-数据库的启动和关闭

下面是工作中对Oracle日常管理操作的一些总结,都是一些基本的oracle操作和SQL语句写法,在此梳理成手册,希望能帮助到初学者(如有梳理不准确之处,希望指出)。 一、数据库的启动和关闭 ORACLE instance started. Total System Global Area  285212672 bytes Fixed Size                  1218968 bytes Variable Size              88082024 bytes Database Buffers          188743680 bytes Redo Buffers                7168000 bytes Database mounted. Database opened. 启动和关闭监听(oracle用户下执行) [oracle@kevin ~]$ lsnrctl start [oracle@kevin ~]$ lsnrctl stop 1.2  数据库的正常关闭步骤 同样以DBA的身份登录数据库 [oracle@kevin ~]$ sqlplus "/as sysdba" 执行数据库关闭命令 SQL> shutdown immediate; Database closed. Database dismounted. ORACLE instance shut down.<br> 1.3 几种关闭数据库方法对比 shutdown有四个参数:normal、transactional、immediate、abort。缺省不带任何参数时表示是normal。 shutdown normal:   不允许新的连接、等待会话结束、等待事务结束、做一个检查点并关闭数据文件。启动时不需要实例恢复,这种方法往往不能关闭数据库或等待很长时间。 shutdown transactional:  不允许新的连接、不等待会话结束、等待事务结束、做一个检查点并关闭数据文件。启动时不需要实例恢复。 shutdown immediate:  不允许新的连接、不等待会话结束、不等待事务结束、做一个检查点并关闭数据文件。没有结束的事务是自动rollback的。启动时不需要实例恢复。最常用的方法。 shutdown abort:  不允许新的连接、不等待会话结束、不等待事务结束、不做检查点且没有关闭数据文件。启动时自动进行实例恢复。一般不推荐采用,只有在数据库无法关闭时使用,可能造成数据库的不一致。 ---------------------------------------------------------------------------------------------------------- Oracle数据库的启动关闭的几种方式 --> 启动数据库 Oracle启动过程涉及几种模式,这些模式涉及不同的文件,每个状态下数据库做不同的事情,同时这些模式适用于不同的维护需求,主要的模式有三种:NOMOUNT、MOUNT、OPEN。 NOMOUNT:启动数据库实例, 此时读取参数文件,但是不加载数据库; MOUNT:启动数据库实例,加载数据库,但是数据库处于关闭状态; OPEN:启动数据库实例,加载并打开数据库; FORCE:终止实例并重启数据库,这种模式在数据库关闭或者启动遇到问题时使用,这种方式不到万不得已时不要使用,会有数据丢失; 1)NOMOUNT 这种模式只会创建实例(创建Oracle实例的各种内存结构与服务进程,其中有5个进程必须启动, DBWR、LGWR、SMON、PMON、CKPT),并不加载数据库,也不会打开任何数据文件。 先关闭数据库 SQL> start nomount; 数据库的启动过程记录在警告追踪文件中,该警告追踪文件中包括数据库启动信息,它存放在参数BACKGOUND_DUMP_DEST定义的目录下,警告日志的名字为alert_orcl.log 进入到目录查看警告日志关于startup nomount过程记录 测试在nomount状态时数据字典是否打的开,下图说明数据库字典在nomount状态下是无法访问的,因为数据字典需要从控制文件获取文件的信息,而此时控制文件没有打开所以无法查看。 但是在nomount下可以通过参数文件获得控制文件的位置,因为此时参数文件已经打开 2)MOUNT 这种模式将启动实例,加载数据库并保持数据库关闭状态。数据库启动到MOUNT状态有两种方式,一是可以直接启动数据库到MOUNT,二是如果数据库已经启动到NOMOUNT状态,使用alter database mount把数据库切换到MOUNT状态; SQL> alert database mount; SQL> startup mount 此时我们可以查看数据字典,因为控制文件已经打开 但是此时不能访问数据库的数据文件(表,视图),文件此时数据文件没有打开。 3)OPEN 这种模式将启动实例,加载并打开数据库,这是常规的启动模式,用户想要对数据库进行多种操作就必须使用OPEN模式启动数据库,启动到OPEN状态,有两种方式,一是直接启动到OPEN状态(使用startup或者startup open),二是如果数据库处于NOMOUNT或者MOUNT状态,可以通过alter database open切换到OPEN状态。 此时可以访问数据文件了 4)FORCE 这种模式将终止实例并重启数据库,这是一种强制性启动模式,只有在启动或者关闭出现问题时才使用,并且有一定的风险,会丢失数据,造成意外的问题。 --> 关闭数据库 与启动数据库顺序相反,也分三个步骤:关闭数据库(CLOSE 关闭数据文件),卸载数据库(关闭控制文件 DISMOUNT),关闭Oracle实例(SHUTDOWN)。同时关闭模式也有多种常见的有: 1)NORMAL 正常的关闭方式,如果对于关闭数据库的时间没有限制,通常采用这种方式,以NORMAL方式关闭数据库,Oracle将执行如下操作: 阻止任何用户建立新的连接; 等待当前所有正在连接的用户主动断开连接; 当前所有用户的都断开连接后,将立即关闭数据库; 2)TRANSACTION 事务关闭方式,它的首要任务是保证当前所有活动的事务都可以被提交,并在尽可能短的时间内关闭数据库。以事务方式关闭,Oracle将执行如下操作: 阻止用户建立新连接和开始新事务; 等待所有活动事务提交后,再断开用户连接; 当所有活动事务提交完毕,用户断开连接后,关闭数据库; 3)IMMEDIATE 立即关闭方式,可以较快且安全的关闭数据库,是DBA经常采用的关闭数据库的方式,立即关闭方式,Oracle执行如下操作: 阻止用户建立新的连接和开始新的事务; 中断当前事务,回滚未提交事务; 强制断开所有用户连接和执行检查点把脏数据写到数据文件中; 关闭数据库 ---------------------------------------------------------------------------------------------------------- oracle几种启动方式说明 ----------------------------------------------------------------------------- 1)startup nomount 非安装启动,这种方式启动下可执行:重建控制文件、重建数据库 读取init.ora文件,启动instance,即启动SGA和后台进程,这种启动只需要init.ora文件。 2)startup mount dbname 安装启动,这种方式启动下可执行: 数据库日志归档、 数据库介质恢复、 使数据文件联机或脱机, 重新定位数据文件、重做日志文件。 执行“nomount”,然后打开控制文件,确认数据文件和联机日志文件的位置, 但此时不对数据文件和日志文件进行校验检查。 3)startup open dbname 先执行“nomount”,然后执行“mount”,再打开包括Redo log文件在内的所有数据库文件, 这种方式下可访问数据库中的数据。 4)startup,等于以下三个命令 startup nomount alter database mount alter database open 5)startup restrict 约束方式启动 这种方式能够启动数据库,但只允许具有一定特权的用户访问 非特权用户访问时,会出现以下提示: ERROR: ORA-01035: ORACLE 只允许具有 RESTRICTED SESSION 权限的用户使用 6)startup force 强制启动方式 当不能关闭数据库时,可以用startup force来完成数据库的关闭 先关闭数据库,再执行正常启动数据库命令 7)startup pfile=参数文件名 带初始化参数文件的启动方式 先读取参数文件,再按参数文件中的设置启动数据库 例:startup pfile=E:\Oracle\admin\oradb\pfile\init.ora 8)startup EXCLUSIVE oracle几种关闭方式说明 ----------------------------------------------------------------------------- 有三种关闭方式: 1)shutdown normal    正常方式关闭数据库。 shutdown有4个参数:shutdown normal(默认)、shutdown immediate(推荐)、shutdown transactional、shutdown abort SQL> shutdown 数据库已经关闭。 已经卸载数据库。 ORACLE 例程已经关闭。 oracle这几种启动和关闭方式之间的区别以及它们各自不同的功能 ----------------------------------------------------------------------------- 1)启动和关闭Oracle数据库 对于大多数Oracle DBA来说,启动和关闭Oracle数据库最常用的方式就是在命令行方式下的Server Manager。从Oracle 8i以后,系统将Server Manager的所有功能都集中到了SQL*Plus中,也就是说从8i以后对于数据库 的启动和关闭可以直接通过SQL*Plus来完成,而不再另外需要Server Manager,但系统为了保持向下兼容,依旧保留了Server Manager工具。另外也可通过图形用户工具(GUI)的Oracle Enterprise Manager来完成系统 的启动和关闭,图形用户界面Instance Manager非常简单,这里不再详述。要启动和关闭数据库,必须要以具有Oracle 治理员权限的用户登陆,通常也就是以具有SYSDBA权限的用户登陆。一般我们常用INTERNAL用户来启动和 关闭数据库(INTERNAL用户实际上是SYS用户以SYSDBA连接的同义词)。Oracle数据库的新版本将逐步淘汰INTERNAL这个内部用户,所以我们最好还是设置DBA用户具有SYSDBA权限。 2)数据库的启动(STARTUP) 启动一个数据库需要三个步骤: -> 创建一个Oracle实例(非安装阶段) -> 由实例安装数据库(安装阶段) -> 打开数据库(打开阶段) 在Startup命令中,可以通过不同的选项来控制数据库的不同启动步骤。 1)STARTUP NOMOUNT NONOUNT选项仅仅创建一个Oracle实例。读取init.ora初始化参数文件、启动后台进程、初始化系统全局区(SGA)。Init.ora 文件定义了实例的配置,包括内存结构的大小和启动后台进程的数量和类型等。实例名根据 Oracle_SID设置,不一定要与打开的数据库名称相同。当实例打开后,系统将显示一个SGA内存结构和大小的列表,如下所示: SQL> startup nomount; ORACLE 例程已经启动。 Total System Global Area 35431692 bytes Fixed Size 70924 bytes Variable Size 18505728 bytes Database Buffers 16777216 bytes Redo Buffers 77824 bytes 2)STARTUP MOUNT 该命令创建实例并且安装数据库,但没有打开数据库。Oracle系统读取控制文件中关于数据文件和重作日志文件的内容,但并不打开该文件。这种打开方式常在数据库维护操作中使用,如对数据文件的更名、改变重作日志以及 打开归档方式等。在这种打开方式下,除了可以看到SGA系统列表以外,系统还会给出\"数据库装载完毕\"的提示。 3)STARTUP 该命令完成创建实例、安装实例和打开数据库的所有三个步骤。此时数据库使数据文件和重作日志文件在线,通常还会请求一个或者是多个回滚段。这时系统除了可以看到前面Startup Mount方式下的所有提示外,还会给出一 个\"数据库已经打开\"的提示。此时,数据库系统处于正常工作状态,可以接受用户请求。假如采用STARTUP NOMOUNT或者是STARTUP MOUNT的数据库打开命令方式,必须采用ALTER DATABASE命令来执行打开数据库的操作。 例如,假如你以STARTUP NOMOUNT方式打开数据库,也就是说实例已经创建,但是数据库没有安装和打开。这是必须运行下面的两条命令,数据库才能正确启动。 SQL> ALTER DATABASE MOUNT; SQL> ALTER DATABASE OPEN; 而假如以STARTUP MOUNT方式启动数据库,只需要运行下面一条命令即可以打开数据库: SQL> ALTER DATABASE OPEN. 4)其他打开方式 除了前面介绍的三种数据库打开方式选项外,还有另外其他的一些选项。 STARTUP RESTRICT 这种方式下,数据库将被成功打开,但仅仅答应一些特权用户(具有DBA角色的用户)才可以使用数据库。这种方式常用来对数据库进行维护,如数据的导入/导出操作时不希望有其他用户连接到数据库操作数据。 STARTUP FORCE 该命令其实是强行关闭数据库(shutdown abort)和启动数据库(startup)两条命令的一个综合。该命令仅在关闭数据库碰到问题不能关闭数据库时采用。 ALTER DATABASE OPEN READ ONLY; 该命令在创建实例以及安装数据库后,以只读方式打开数据库。对于那些仅仅提供查询功能的产品数据库可以采用这种方式打开。 2.2  用create user语法创建用户 SQL> CREATE USER user_name IDENTIFIED BY user_passwordDefaultTablespace tbs_users; user_name为数据库用户的用户名 user_password为数据库用户的密码 tbs_users为用户使用的表空间,默认是users表空间。 SQL> CREATE USER cmsuser IDENTIFIED BY passwordDefaultTablespace users; 2.3  赋表空间使用权限 SQL> alter user user_name quota unlimited on user_tablespace quota unlimited on user_tablespace; 2.4  给用户赋权限 SQL> GRANT connect, resource TO cmsuser; Connect用户能登录数据库的权限 Resource用户能创建一些数据库对像的权限,表、视图,存储过程,一般是授予开发人员的 2.5  删除用户 SQL> DropUser cmsuser Cascade; 使用cascade参数可以删除该用户的全部objects

35岁前必须做好的10件事情(转载)

35岁是青春的后期,35岁以后是收获的季节,如果你没有资格说这句话,你将会憎恨自己。         所以在35岁以前,在烂漫蓬勃的青春年华里,你最好把下面十件事做好!   第一,学会本行业所需要的一切知识并有所发展。已故零件大王布鲁丹在他35岁时  ,已经成为零件行业的领袖,并且组建了年收入达千万美元的海湾与西部工业公司。每个人在年轻时都可能有过彻夜不眠、刻苦攻读,这在20岁甚或30岁都没有问题,但到了35岁,就不应该再为学习基本技能而大伤脑筋了。35岁之前是一个人从事原始积累的阶段,35岁之后就应该勃发了。   第二,养成个人风格。在35岁以前,找出你所喜欢的,不论是衣着或是爱好,哪怕是与众不同的小习惯也好。20岁、30岁时你可以不断尝试、不断改变,但是到了35岁,你便要明确地建立个人风格。一位男士或女士在事业中途改变自己的形象,就会让人觉得很不可*。你喜欢穿西装吗?好!就把西装当作你的商标吧!办公桌上摆些鲜花会令你工作更有效率吗?那就每天都摆些鲜花吧!   第三,在感情生活方面平和安定。在攀登事业的高峰时,如果私人生活不愉快,陷入感情危机,对你会产生很大的干扰,甚至会逐渐令你对别的事物失去兴趣。那些在35岁之前私人生活已经平和安定的人,一般都比生活动荡不安的人有更大的机会获得成功。因此,如果你想结束一段没有结果的恋情,或者你想和女友结婚,那就赶快行动吧,免得把问题拖到生命的第35个春秋。在35岁以后,你应该专注地看着你对事业的投资开始获利。   第四,明白自己的短处。承认有些事情你的确做不好,或者不愿做。如果你讨厌数字而喜欢创作,那就不要因为待遇高或顺从别人的期望而强迫自己做数字工作。在35岁之前,一定要投入你所喜爱、所擅长的那种工作。否则,35岁之后必然会有一段郁郁不乐的日子。而且,真正的成功可能因为活力的消退而丧失。   第五,知道自己的长处。你应该知道自己擅长什么,并且清楚你所喜欢做而又做得比别人好的事情。不管你目前担任什么样的角色,知道自己的长处对成功都很重要。   第六,储备辞职另谋生路的钱。在这个多变的职业世界里,你也许不会永远在一个地方工作,或者永远在一个位置上淋漓尽致地发挥自己,当你感到无法施展时,你很可能会想到辞职,或者开辟第二职业,如果你事先储蓄了足够的钱,你便有了一个安全的后盾。   第七,建立人际关系网。如果到了35岁你仍未建立起牢固的人际关系网,那你就有麻烦了。这个人际关系网包括你的朋友、亲人,最低限度包括所有可以互相帮助的人。这些人有的是你的同事,有的受过你的恩惠,有的你倾听过他们的问题,有的你和他有着相同的爱好。人际关系网不是一朝一夕就能建立起来的,它需要几年甚至十几年的培养。一个人在事业上、生活上的成功其实如同一个政党的成功,你要有许多人散布在适当的地方,你可以依赖他们,他们也可以依赖你。   第八,学会授权他人。许多人不肯或不能这样做,因此始终被钉在从属的职位上。授权他人是成功的一半,一个事无巨细,不能将工作授权别人的人,注定会遇到极大的障碍。到了35岁,你最好已成为这方面的专家。换言之,你懂得挑选合适的人并信任他们。   第九,学会在什么时候三缄其口。因说话不小心而自毁前程的人,比因为任何其他原因丧失成功的人都多。要学会保持沉默而且看起来机智--别人自然以为你知道的比实际还多。别讲别人的闲话,别谈论你自己的大计,守口如瓶所赢得的声誉,远比讲人闲话所带来的东西更加珍贵。你在事业上越成功,这一点就越重要。   第十,对人要忠诚。如果你到了35岁仍未能建立起坚如磐石的忠诚信誉,这一缺点将会困扰你一生。不忠诚的恶名必然会使你在事业上到处不受欢迎。你不能*暗箭伤人爬到事业的顶峰,而要*在早期树立起来的真诚刚直和不可动摇的声誉。35岁以前,忠诚只是投资;35岁以后,你会作为一个可以信赖的人收到忠诚的回报。          今天偶然在网上看到了这篇文章,认真看后觉得还是很有道理的,转贴过来,用来勉励自己! 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2006/01/18/319317.html,如需转载请自行联系原作者

Head First Design Patterns(深入浅出设计模式)-目录

目录序你的大脑是如何理解设计模式的?此时,你正在设法学习些知识,而你的大脑要通过确认这些知识来给你提供支持。你的大脑在想:“最好出去做些更重要的事情,就象消灭野兽或者光着身子滑雪不是个好主意”。所以你要怎么样让你的大脑认为你的生死存亡都依赖于设计模式的知识? 1.Welcome to Design Patterns - 设计模式介绍 有人已经解决了你的问题。在这章里,你将学习到为什么(和怎么样)你可以使用其他已经走过相同设计问题的路并幸存下来的开发者的智慧和教训。在我们做之前,我们将先看看设计模式的用途和好处,再看一些关键的面向对象设计原则,并且再通过一个实例了解模式的工作方式。使用模式最好的方法就是把它们装入脑袋里,然后在你设计和现有的应用程序里认出你能够应用它们的地方。相对于代码重用,使用模式你获得了经验的重用。模拟鸭子乔相对继承利用接口怎么样?软件开发的一个不变的真理分开变动和不变动的部分设计鸭子的行为测试鸭子的代码动态地设置行为封装行为的大局观『有一個』可能比『是一個』更好策略模式共享模式词汇的力量我如何使用设计模式?设计工具箱里的工具练习解答 2.Keeping your Objects in the Know - 观察者模式 不要遗漏有趣的事情!我们已经有一个模式,它可以使你的对象知道它们关心的某些事情在发生的时候的内幕。对象甚至可以决定是否在运行的时候仍然知道内幕(be kept informed)。观察者模式是JDK中使用最多的模式之一,它是难以置信的有用。在我们做之前,我们同样先看看一对多关系和释放偶合(是,就是它,我们说偶合). 同观察者一起,你们将是模式大家庭的一员。气象检测系统认识观察者模式出版者 + 订阅者 = 观察者模式五分钟短剧: 值得观察的主题定义观察者模式松偶合的力量设计气象站实现气象站使用Java内建的观察者模式java.util.Observable 的黑暗面设计工具箱里的工具练习解答 3.Decorating Objects - 装饰者模式 就叫这章为"继承的设计眼光"("Design Eye for the Inheritance Guy")。我们将重新检查继承的典型的过度使用,同时你将学习到在运行的时候怎么样使用对象组合的方式来装饰你的类。为什么?一旦你熟悉了装饰的技巧,你将可以在不修改任何基础的类的情况下给你的(或其他人的)对象赋予新的职责。欢迎来到星巴兹咖啡 开放关闭原则认识装饰者模式使用装饰者构建饮料订单定义装饰者模式装饰饮料写下星巴茲的代码真实世界的装饰者:Java I/O设计自己的 Java I/O 装饰者设计工具箱里的工具练习解答 4.Baking with OO Goodness - 工厂模式 准备好来设计一些松偶合的面向对象的设计。除了使用new操作以外,还有很多制造对象的方法。你将学习到 实例化(instantiation)是一种不总是公开的被执行并且能够经常导致偶合问题的一种行为。然而,你不希望那样,不是吗?发现工厂模式怎么把你从糟糕的依赖关系中拯救出来。当看到『new』,就要联想到『具体』对象村比萨封裝创建对象的代码建立一个简单的比萨工厂定义简单工厂给比萨店使用的框架允许子类做决定让我们开一家比萨店声明一个工厂方法认识工厂方法模式平行的类层次定义工厂方法模式一个很依赖的比萨店看看对象的依赖性依赖倒置原则回到比萨店...原料家族建立原料工厂看看抽象工厂幕后花絮定义抽象工厂模式比较工厂方法和抽象工厂设计工具箱里的工具练习解答 5.One of a Kind Objects - 单态模式 单态模式:你用来创建哪些只有一个实例的对象的入场卷。你可能因为在所有的模式的类图中单态的类图是最简单的而高兴;事实上它的类图只有一个单独的类!但是不要太乐观;尽管从类图上看它非常简单,但是我们实现它的时候将遭遇相当多阻挠和陷阱。所以,清醒一下-它并不像看起来那么简单……独一无二小小单态剖析经典单态模式单态的供认巧克力工厂定义单态模式休斯顿,我们遇到麻烦了...化身为 JVM处理多线程单态的 Q&A设计工具箱里的工具练习解答 6.Encapsulating Invocation - 命令模式 在这章里我们要把封装带到一个全新的层次:我们将封装方法的调用。是啊,通过封装调用我们可以明确一系列的计算(computation),所以对象在调用计算(computation)的时候不需要关心它是怎么做的;它仅是使用我们明确的方法来获得行为。我们还可以使用封装方法调用的方式来做一些耍小聪明(wickedly smart)的事情,例如在我们的代码记录请求日志或重用它们来实现撤销功能。家电自动化公司遥控器看一下厂商的类别同時,回到餐厅...研究餐厅的互动过程对象村餐厅的角色和责任从餐厅到命令模式第一个命令对象定义命令模式命令模式与遥控器实现遥控器逐步测试遥控器写文件的时候到了使用状态实现撤消每个遥控器都需要具备集合形式!使用宏命令命令模式的更多用途:队列请求命令模式的更多用途:日志请求设计工具箱里的工具练习解答 7.Being Adaptive - 适配器和门面模式 在这章里我们将尝试一些不可能的技艺,就象把一个正方形的木栓插入一个圆孔中。在我们还没有设计模式的时候这听起来是不可能的?你还记得装饰者模式吗?我们通过包装一个对象来赋予它新的职责。现在我们将包装一些不同用途的对象:使它们的接口看起来象是其它东西。我们为什么要这么做呢?因为这样我们可以把一个接口改装成不同的接口。这些并不是全部,我们还将看到另一个模式,它可以通过包装对象来简化它们的接口。我们周围的适配器OO适配器解释适配器模式定义适配器模式对象和类的适配器今晚的话题:对象适配器和类适配器真实世界的适配器将列举适配到迭代器今晚的话题:装饰者模式和适配器模式甜蜜的家庭剧院灯光,照机,门面!构建家庭剧院的门面定义门面模式「认识最少」原则设计工具箱里的工具练习解答 8.Encapsulating Algorithms - 模板方法模式 我们已经封装了对象的创建,方面的调用,联合的接口,鸭子,比萨饼...下一个封装什么?我们将开始考虑封装算法,所以使子类在任何时候都可以正确地挂钩(hook)自己到算法中。我们还有学习一个从好莱坞得到的灵感的设计原则。写一些咖啡和茶的类抽象咖啡和茶更进一步的设计抽象PrepareRecipe()我们做了什么?认识模板方法让我们泡茶去模板方法带给我们什么?定义模板方法模式再靠近一点对模板方法进行挂钩使用挂钩咖啡?茶?执行测试程序好莱坞原则好莱坞原则和模板方法荒野中的模板方法用模板方法排序排序鸭子比较鸭子排序鸭子的制造方法写一个Swing 的视窗程序Applet今晚的话题:模板方法和策略方法设计工具箱里的工具练习解答 9.Well-Managed Collections - 迭代器和合成模式 有很多方法可以把对象填充到集合里。把它们放到数组里,堆栈里,列表里,地图里,随你便。每种方法都有自身的优缺点。但是当你的客户想要从头到尾迭代你的对象的时候,你是否需要展示你的实现方式。我们确信不需要!那是不专业的。不用担心-在这章里你将了解到怎么样使你的客户在不了解你是怎么样存储对象的情况下就可以从头到尾地迭代你的对象。你可以学习到怎么样创建一些强大的对象集合,这些集合中的对象能够在一个单一的绑定中跳过一些特定的数据结构。你还可以学习到一两件关于对象职责的事情。合并对象村餐厅和煎饼屋比较菜单的实现方式我们可以封装迭代操作吗?认识迭代器模式在餐厅菜单中加入一个迭代器看看现在的设计使用java.util.Iterator改写程序这给我们带来了什么?定义迭代器模式单一责任迭代器和集合Java 5 的迭代器和集合正当我们认为这很安全的时候...定义合成模式使用合成设计菜单实现合成菜单倒叙到迭代器空迭代器迭代器和合成在一起的魔力...设计工具箱里的工具练习解答 10.The State of Things - 状态模式 公认的事实:策略和状态模式是孪生兄弟。就象你所知道的,策略模式通过可互换的算法规则来创建非常成功的业务模式(wildly successful business)。不管怎么样,状态以非常高尚的方式帮助对象学习通过他们内部的状态来控制他们的行为。他总是无意中告诉他的对象客户,"跟着我重复就行了,我足够好,我足够聪明,..."我们怎么样实现状态状态机第一版状态机该来的躲不掉...需求改变!混乱的状态...定义状态的接口和类实现我们的状态类重新改造糖果机定义状态模式状态模式vs策略模式状态精神检查我们差点忘了!设计工具箱里的工具练习解答 11.Controlling Object Access – 代理模式 究竟扮演好警察还是坏警察?你是一个好警察,你所有的服务都很和蔼和友好,但是你不想所有人都要求你的服务,所以你需要坏警察来控制对你的访问。那就是代理要做的事情:控制和管理访问。就象你将看到的一样,有很多方法可以代表他们代理的对象。代理可以在网络上为他们代理的对象的完整的方法访问改变方向(Proxies have been known to haul entire method calls over the Internet for their proxied objects);代理还可以持久地替代一些可爱的懒对象。监控糖果机远程代理的角色RMI巡礼糖果机远程代理远程代理幕后花絮定义代理模式准备虚拟代理设计CD封面的虚拟代理虚拟代理的幕后花絮使用 Java API 的代理五分钟短剧:保护主角建立动态代理代理动物园设计工具箱里的工具练习解答 12.Patterns of Patterns – 复合模式 谁曾经会想到模式能够在一起工作?你已经亲眼目睹了激烈的家庭辩论(并且感谢你没有不得不看到出版商强迫我们从书里移除的模式死亡竞赛(Pattern Death Match),所以我们能够避免不得已去使用模式警告标签),所以谁将会考虑到模式可以在实际中融洽相处?你是否相信,一些最强大的OO设计都同时使用了多个模式。准备好提升你的模式技巧到下一个层次;该是介绍复合模式的时候了。要小心-你的同事可能会杀了你,如果你由于对模式的狂热而罢工的话。复合模式鸭子重出江湖加入一个适配器加入一个装饰者加入一个工厂加入一个合成和一个迭代器加入一个观察者模式总结从鸭子的角度看类图Model-View-Controller 之歌设计模式是MVC的关键戴上模式的有色眼睛看 MVC使用MVC控制节拍…ModelViewController探索策略模式Model的适配现在我们已经准备好心脏控制器将MVC应用于Web设计模式与Model设计工具箱里的工具练习解答 13.Patterns in the Real World – 与设计模式相处 现在你已经准备好已经一个充满设计模式的时间。但是,当你打开所有机会大门之前,我们要告诉你一些在真实世界会遇到的细节—外面的世界比对象村要复杂。来吧,我们会给你指引方向,帮助你适应…对象村指南定义设计模式更仔细地观察设计模式的定义愿力量与你同在模式目录怎么样创建模式想当一个设计模式作家吗?组织设计模式用模式思考模式的心智不要忘了共通词汇表的力量共同词汇表的五种方式和四人帮一同巡回对象村你的旅途刚开始…其他设计模式的资源模式动物园用反模式消灭恶势力设计工具箱里的工具离开对象村… 14.附录:剩下的模式 并非所有人都能成为最受欢迎的人。过去10年里改变了很多事情。自从<设计模式-可复用面向对象软件的基础>一书出版以来,开发者已经应用了无数次那些模式。我们在这个附录里总结的模式都是标准的,正式的GOF模式,但是它们在我们以往的探索中并不经常被使用。但是这些模式都有存在的价值,如果你设身处地的为它们着想,你将使用你的头脑更深入地掌握它们。我们在这个附录里的目标就是带给你关于所有这些模式的更高层次的观点。桥梁模式建造者模式责任链模式享元模式翻译者模式协调者模式(Mediator)纪念品模式(Memento)原形模式访问者模式//----------------------------题外话-------------------------------------经过几天空余时间的努力,终于翻译完了这本书的第一部分:目录.由于是第一次正式翻译东西,肯定有很多地方都不准确,大家一定要带着怀疑的目光去看我的译文,帖出来也是希望大家多提宝贵意见.由于这本书里使用了大量生动有趣的图片和无处不在的比喻,所以大家最好弄一本书来看,然后我们再到这里一起交流心得,我会坚持把以后的章节都翻译出来的. 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2006/03/23/356523.html,如需转载请自行联系原作者

摆摆控件,就可以实现多功能(提交、修改、浏览)的表单了[原]

最近封了一个简单的类库,主要目的是帮助实现简化制作表单页面的工作。使得制作一个具有提交、修改、浏览功能的表单页面,只需要摆好控件再写很少量的代码即可。在需求发生变动需要调整UI的时候,也仅是调整控件的摆放而已。而且还可以根据工作的流程制作多套表单,在实际使用的时候,根据流程不同来动态切换。这里发个简单的Demo,实际要比这复杂一些,但是Demo已足够阐述实现原理,目的也就达到了。 下面做简单的介绍,具体看代码。(代码是ASP.Net2.0/VS2005的,在C/S里的实现,原理也是一样的。) 1.表单上的控件ID名称需要同对应的实体的数据字段名相同。(以此为依据映射数据) 一、使用步骤:1、引用Justin.UILibrary.dll; 2、添加一个用户自定义控件DemoUI.ascx; 3、摆放表单控件,简单演示如下图: 红色部分为自定义校验控件,这里只是个演示,实际中怎么弄随便了。 4、修改用户控件的代码如下: 5、到此,一个只管收集数据,显示数据,修改数据的UI用户自定义界面就做好了。下面需要在页面上使用这个用户自定义控件。Go on … 6、在页面需要显示这个表单的地方放一个PlaceHolder控件,这么做是为了可以动态加载用户自定义控件,从另一个角度来说,这也实现了动态替换不同的用户自定义控件功能,比如你有多个表单需要在不同的情况下动态切换,那么,使用PlaceHolder控件,再配合XML配置文件,一切就OK了。 7、然后在页面的*.aspx.cs里添加如下代码: 8、Ctrl+F5执行程序,一切就OK了! 二、效果演示:a、提交的时候(除了下拉框,其它都为空): b、浏览的时候(所有控件不可用) c、修改状态(界面上有数据,为待编辑状态)三、Deom总结 最后画了一个简单的顺序图,说明一下程序内部是如何执行的。其中,关于XML的部分在Demo里没有做,只是用注释标明了一下,这个很简单,但是功能却很强大,可以让你在运行时动态决定界面加载哪个预定义的表单用户自定义控件,所以有必要在图中画了一下。四、关于Justin.UILibrary.dll 最后我们再简单说一下Justin.UILibrary.dll,有了它,使得制作表单的大部分工作变成了摆控件,它把报单里可以抽出来的东西尽量都封装了起来,使得大部分代码工作都得到了重用。这里简单说一下最核心的UI.cs类,它是表单控件的基类,如上面的步骤4所示,继承它之后,只需要附加很少的代码,即可以完成表单的后台代码工作。当然,这里提供的都是最基本的功能,如果用户自己有任何其他字定义功能,都可以自己在继承的基础上再进行扩展。其中比较关键的几个地方是: 1.ExecActionEvent()方法 这个方法使用委托的机制,将最终按钮的功能如何实现抛出来由用户自己去实现,WHY?因为鬼才知道用户会做什么,这是封装控制不了的因数,所以要抛出去。 2.InitControl(UIType type)方法 这里相当于模板方法模式的应用,内部在不同状态下调用的三个virtual方法,给了SubCalss一个插入功能的机会,即,可以分别在提交、浏览、修改的状态下初始化界面时,加入自定义的功能。如步骤4中所做的,在提交的时候,将按钮的标题改为“提交”,在修改的时候,将按钮的标题改成“保存”,当然,用户自己还可以做很多别的什么事情,这个灵活性是封装的基类不去关心的,基类只提供“工作机会”,至于工作的怎么样,自己看着办吧。 如下图所示:五、代码下载 JustinDemo: http://files.cnblogs.com/justinw/JustinDemo.rar Justin.UILibrary: http://files.cnblogs.com/justinw/Justin.UILibrary.rar 虽然这里还只是演示代码,部分地方还有待完善,但是这篇文章主要想说的是如何通过封装来重用和简化代码工作,重要的是其中的原理和思想,还希望各位朋友看过代码后多提宝贵意见。 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2006/10/04/520924.html,如需转载请自行联系原作者

.NET调试实例-实验1:死锁 - 回顾 (原创翻译)

原文地址:http://blogs.msdn.com/tess/archive/2008/02/06/net-debugging-demos-lab-1-hang-review.aspx译者注释 (Just do it)1、这篇文章是作者对上篇文章的回顾和总结,作者详细解答了在上篇文章里留给读者思考的问题,并循序渐进地将问题逐层展开。 2、关于死锁,这两篇文章提到的都是比较基础的内容,稍后我准备结合这个实验的问题对这部分内容做一定的扩展,敬请期待! 希望大家能真正亲自动手实践,然后踊跃留言啊!本周早些时候,我发布了第一个.NET调试实例。如果你还没有下载和动手实践这个实验,你可以从<这里>获得。这篇文章是这个实验的回顾,在这里解答了上篇提出的问题,答案都标识为红色。提示:实验结果和线程ID都取决于你刷新页面时点的多快和你机器的配置以及当时还有其它什么线程的请求正在执行,所以我将依据在我的双核+Win2003的机器上得到的结果来回答上篇文章的问题。重现问题:1.浏览 http://localhost/BuggyBits/FeaturedProducts.aspx 这个页面将延时5秒显示,你能在页面底部看到开始时间和执行时间。2.打开5个以上的浏览器同时浏览这个页面,并且同时刷新。注意每一个页面的执行时间并确保它们的开始时间几乎都完全一样。(如果开始时间不同,你有可能是没有执行那个reg文件)Q:执行时间怎么样?A: 浏览器1 - 5.0s,浏览器2 - 9.1s,浏览器3 - 12.57s,浏览器4 - 16.07s,浏览器5 - 18.61s (如果你没有看到执行时间是逐渐增长的,那就应该检查一下是否执行了那个reg文件,如果没有执行,看到的结果就是所有的请求的开始时间都有5秒钟的延时)Q:问题重现的时候,w3wp.exe进程的CPU利用率怎么样?高还是低?A: 非常低的CPU利用率,大约 0-5%Q:出现死锁症状的潜在原因是什么?A:根据请求时间是逐渐增长的和CPU的利用率一直都很低,这说明:a)我们正在等待某些一次只能被一个线程使用的公共资源。b)我们并没有在一个死循环中,看起来我们像是因为等待某些外部的资源而被阻塞的。获取内存转储文件:1.打开一个命令行窗口,然后进入到你的调试器工具集目录。输入下面的命令行准备获取转储文件,但是暂时先不要执行。adplus –hang –pn w3wp.exe –quiet提示: quiet开关是用来让我们不必处理那些询问信息的弹出提示框,因为在请求结束前我们没有那么多时间处理完这些后再得到内存转储文件。你一般会得到一个消息提示框询问你是否要把当前的脚本(script)设置为你的默认脚本,或者是提示你还没有在系统默认环境变量里设置符号文件路径,或者是提示你正在收集一个挂起模式的内存转储文件。一般情况下,对于这些提示信息,你都可以简单地点yes。2.重现问题,使用刚才同时刷新5个浏览器的方法或者通过下面的命令行使用tinyget给那个网页施压的方法。tinyget -srv:localhost -uri:/BuggyBits/FeaturedProducts.aspx -threads:30 -loop:50提示:这个命令将启动30个线程,并且发送50个请求到 FeaturedProducts.aspx3.在刚才的adplus窗口敲回车就可以在所有请求正在执行的时候获得内存转储文件。Q:adplus处于挂起模式的时候,什么触发了生成内存转储文件?A:这是一个带点欺骗性的问题。之所以会产生Dump文件是因为你正在运行adplus,它并不是在等待满足一个死锁的条件或者其他条件而触发生成Dump文件(不同于-crash开关),所以你可以在任何时候使用-hang开关来得到一个Dump文件,而不需要考虑线程是否真的处于死锁中,这种方式也是在诊断高内存使用率问题的时候常用的方法。Q:你需要有什么样的权限才可以获取到一个进程的内存转储文件?A:在权限方面,使用windbg/adplus进行调试跟使用其它的调试器没有什么区别,你需要能持有那个进程或更高的权限。在hang模式下,因为内存转储文件是以非侵入方式被抓取的,这意味着我们根本没有中断进入线程,所以你不需要跟启动进程有相同的身份,在客户端调试服务器时,以hang模式抓取内存转储文件的方式很实用。在crash模式下,正好相反,你需要跟启动进程等帐号有相同的身份,这意味着如果你是在客户端或远程桌面登录到服务器端,那么你需要在控制台登录到服务器端。Q:转储文件被创建在那里? 提示:查阅一下Windbg的帮助文件,关于adplus/挂起模式部分。A:内存转储文件默认保存在每次你运行adplus时(使用-hang或-crash模式)在调试器的目录里新建的文件夹中,这个文件夹将以这样的格式命名:“C:\debuggers\32bit\Hang_Mode__Date_02-06-2008__Time_11-15-0505”。文件夹里包含下面这些东西:     * CDBScripts - 包含用来通知windbg/cdb运行什么命令的配置文件的文件夹。     * ADPlus_report.txt - 记录adplus附加到进程以后的信息     * PID-5656__W3WP.EXE__Date_02-06-2008__Time_11-15-0505.log - adplus的运行时日志,在hang模式下,这个文件里包括堆栈里所有线程、已经加载的模块的信息和等同于执行!runaway命令的输出结果。如果内存转储文件创建失败,那么你可以到这个文件的底部去查找原因。     * PID-5656__W3WP.EXE__full_1c38_2008-02-06_11-15-08-005_1618.dmp - 这就是内存转储文件。     * Process_List.txt - tlist.exe 的输出,显示在抓取内存转储文件的时候,系统中有多少进程在同时运行。使用windbg.exe打开转储文件1.启动Windbg,使用"File/Open Crash dump"菜单打开刚才获得的内存转储文件。2.设置符号文件的路径 (具体参考:信息和安装说明)3.加载SOS (具体参考:信息和安装说明)检查堆栈1.检查本地调用堆栈~* kb 2000  2.检查.NET调用堆栈~* e !clrstackQ:你是否发现了一些某个线程正在等待其它同步机制的典型迹象或者在调用堆栈上看出某些可能性?A:内存转储文件里有很多类似下面这样的本地调用堆栈的线程,斜体部分因为是托管的调用堆栈,Windbg不能显示其完整信息。0:066> k 2000ChildEBP RetAddr 1156e7b0 7d4e286c ntdll!ZwWaitForMultipleObjects+0x15 1156e858 79ed98fd kernel32!WaitForMultipleObjectsEx+0x11a 1156e8c0 79ed9889 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f1156e8e0 79ed9808 mscorwks!Thread::DoAppropriateAptStateWait+0x3c1156e964 79ed96c4 mscorwks!Thread::DoAppropriateWaitWorker+0x13c1156e9b4 79ed9a62 mscorwks!Thread::DoAppropriateWait+0x401156ea10 79e78944 mscorwks!CLREvent::WaitEx+0xf71156ea24 79ed7b37 mscorwks!CLREvent::Wait+0x171156eab0 79ed7a9e mscorwks!AwareLock::EnterEpilog+0x8c1156eacc 79f59024 mscorwks!AwareLock::Enter+0x611156eb34 79fc6352 mscorwks!AwareLock::Contention+0x1991156ebd4 0ff10dd3 mscorwks!JITutil_MonContention+0xa3WARNING: Frame IP not in any known module. Following frames may be wrong. 1156ec34 793ae896 0xff10dd3 1156ee8c 6614d8c3 mscorlib_ni+0x2ee896 1156eec4 6614d80f System_Web_ni+0x22d8c3 1156ef00 6614d72f System_Web_ni+0x22d80f 1156ef20 65fe6bfb System_Web_ni+0x22d72f 1156ef54 65fe3f51 System_Web_ni+0xc6bfb 1156ef90 65fe7733 System_Web_ni+0xc3f51 1156efe4 65fccbfe System_Web_ni+0xc7733 1156eff8 65fd19c5 System_Web_ni+0xacbfe 1156f01c 7938111c System_Web_ni+0xb19c5 00000000 00000000 mscorlib_ni+0x2c111c  下面的是托管调用堆栈0:066> !clrstackOS Thread Id: 0x960 (66)ESP       EIP     1156ea4c 7d61d051 [GCFrame: 1156ea4c] 1156eb88 7d61d051 [HelperMethodFrame: 1156eb88] System.Threading.Monitor.Enter(System.Object)1156ebdc 0ff10dd3 DataLayer.GetFeaturedProducts()1156ec18 0ff10c6c FeaturedProducts.Page_Load(System.Object, System.EventArgs)1156ec58 66f12980 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)1156ec68 6628efd2 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)1156ec78 6613cb04 System.Web.UI.Control.OnLoad(System.EventArgs)1156ec88 6613cb50 System.Web.UI.Control.LoadRecursive()1156ec9c 6614e12d System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)1156ee98 6614d8c3 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)1156eed0 6614d80f System.Web.UI.Page.ProcessRequest()1156ef08 6614d72f System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)1156ef10 6614d6c2 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)1156ef24 0ff10205 ASP.featuredproducts_aspx.ProcessRequest(System.Web.HttpContext)1156ef28 65fe6bfb System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()1156ef5c 65fe3f51 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)1156ef9c 65fe7733 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)1156efec 65fccbfe System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)1156f008 65fd19c5 System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)1156f03c 65fd16b2 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)1156f048 65fcfa6d System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32)1156f258 79f047fd [ContextTransitionFrame: 1156f258] 1156f28c 79f047fd [GCFrame: 1156f28c] 1156f3e8 79f047fd [ComMethodFrame: 1156f3e8]  如果将它们放在一起,这些线程的调用堆栈看起来像下面这样0:066> k 2000ChildEBP RetAddr  1156e7b0 7d4e286c ntdll!ZwWaitForMultipleObjects+0x15 1156e858 79ed98fd kernel32!WaitForMultipleObjectsEx+0x11a 1156e8c0 79ed9889 mscorwks!WaitForMultipleObjectsEx_SO_TOLERANT+0x6f1156e8e0 79ed9808 mscorwks!Thread::DoAppropriateAptStateWait+0x3c1156e964 79ed96c4 mscorwks!Thread::DoAppropriateWaitWorker+0x13c1156e9b4 79ed9a62 mscorwks!Thread::DoAppropriateWait+0x401156ea10 79e78944 mscorwks!CLREvent::WaitEx+0xf71156ea24 79ed7b37 mscorwks!CLREvent::Wait+0x171156eab0 79ed7a9e mscorwks!AwareLock::EnterEpilog+0x8c1156eacc 79f59024 mscorwks!AwareLock::Enter+0x611156eb34 79fc6352 mscorwks!AwareLock::Contention+0x1991156ebd4 0ff10dd3 mscorwks!JITutil_MonContention+0xa31156ea4c 7d61d051 [GCFrame: 1156ea4c] 1156eb88 7d61d051 [HelperMethodFrame: 1156eb88] System.Threading.Monitor.Enter(System.Object) 1156ebdc 0ff10dd3 DataLayer.GetFeaturedProducts()1156ec18 0ff10c6c FeaturedProducts.Page_Load(System.Object, System.EventArgs)1156ec58 66f12980 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)1156ec68 6628efd2 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)1156ec78 6613cb04 System.Web.UI.Control.OnLoad(System.EventArgs)1156ec88 6613cb50 System.Web.UI.Control.LoadRecursive()1156ec9c 6614e12d System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)1156ee98 6614d8c3 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)1156eed0 6614d80f System.Web.UI.Page.ProcessRequest()1156ef08 6614d72f System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)1156ef10 6614d6c2 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)1156ef24 0ff10205 ASP.featuredproducts_aspx.ProcessRequest(System.Web.HttpContext)1156ef28 65fe6bfb System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()1156ef5c 65fe3f51 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)1156ef9c 65fe7733 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)1156efec 65fccbfe System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)1156f008 65fd19c5 System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)1156f03c 65fd16b2 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)1156f048 65fcfa6d System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32)1156f258 79f047fd [ContextTransitionFrame: 1156f258] 1156f28c 79f047fd [GCFrame: 1156f28c] 1156f3e8 79f047fd [ComMethodFrame: 1156f3e8] 那么我们可以从这个调用堆栈里看到(像在Visual Studio里查看调用堆栈一样,从下往上看) FeaturedProducts.Page_Load 调用了一个DataLayer.GetFeaturedProducts()方法,这个方法又调用了Monitor.Enter() 方法,这是在.NET中使用锁(lock)的实现方式。GetFeaturedProducts 方法的代码应该看起来像下面这样void GetFeaturedProducts(){   lock(){     // do something }因为已经有其他线程占用这个锁,所以我们就卡在lock(...)这行。 定位并解决死锁1.确定持有锁的线程的ID.!syncblkQ:什么线程拥有锁?A:我的!syncblk执行结果如下:0:066> !syncblkIndex  SyncBlock    MonitorHeld Recursion Owning Thread Info  SyncBlock  Owner20      001c6f74     85              1              0f4a0a70 1ea0 30   02f07964   System.Object-----------------------------Total 22CCW 2RCW 0ComClassFactory 0Free 5 Free 5  拥有锁的线程是Owning Thread Info字段里最后一列(在这里是线程30),那么这就是上面的GetFeaturedProducts()方法里"// do something"那部分的线程,或者是其它占用了我们需要的锁的线程。Q:有多少线程在等待解锁?提示:MonitorHeld = 1时表示这个线程持有锁,MonitorHeld = 2时表示这个线程被阻塞!A:这里MonitorHeld字段的值是85,这意味着我们有一个锁拥有者和84/2=42个等待者,也就是说有42个请求都在等待这个锁,如果我执行 .shell -ci "~* e !clrstack" FIND /C Monitor.Enter 看看有多少调用堆栈里有Monitor.Enter,返回结果是42,这与上面的推测一致。事实上,42是生活、宇宙和所有事情的答案,这只是一个巧合 :)2.挑选一个堵塞线程(提示:堵塞线程位于AwareLock::Enter),看看它在做什么?    ~5s              (切换到线程5)    kb 2000         (检查本地堆栈)    !clrstack        (检查.NET堆栈)Q:堵塞线程等待的锁在那个.NET函数里? A: DataLayer.GetFeaturedProducts()3.检查持有锁的线程在做什么?    ~5s             (切换到线程5)    kb 2000        (检查本地堆栈)    !clrstack       (检查.NET堆栈)Q:为什么会发生死锁?从线程30可以看到,DataLayer.GetFeaturedProducts()方法调用了Thread.Sleep(),那么这就完全可以解释为什么我们都堵塞在那了(拥有锁的线程)。0:030> !clrstackOS Thread Id: 0x1ea0 (30)ESP       EIP     1036ec88 7d61cca8 [HelperMethodFrame: 1036ec88] System.Threading.Thread.SleepInternal(Int32) 1036ecdc 0ff10ddd DataLayer.GetFeaturedProducts()1036ed18 0ff10c6c FeaturedProducts.Page_Load(System.Object, System.EventArgs)1036ed58 66f12980 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr, System.Object, System.Object, System.EventArgs)1036ed68 6628efd2 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(System.Object, System.EventArgs)1036ed78 6613cb04 System.Web.UI.Control.OnLoad(System.EventArgs)1036ed88 6613cb50 System.Web.UI.Control.LoadRecursive()1036ed9c 6614e12d System.Web.UI.Page.ProcessRequestMain(Boolean, Boolean)1036ef98 6614d8c3 System.Web.UI.Page.ProcessRequest(Boolean, Boolean)1036efd0 6614d80f System.Web.UI.Page.ProcessRequest()1036f008 6614d72f System.Web.UI.Page.ProcessRequestWithNoAssert(System.Web.HttpContext)1036f010 6614d6c2 System.Web.UI.Page.ProcessRequest(System.Web.HttpContext)1036f024 0ff10205 ASP.featuredproducts_aspx.ProcessRequest(System.Web.HttpContext)1036f028 65fe6bfb System.Web.HttpApplication+CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()1036f05c 65fe3f51 System.Web.HttpApplication.ExecuteStep(IExecutionStep, Boolean ByRef)1036f09c 65fe7733 System.Web.HttpApplication+ApplicationStepManager.ResumeSteps(System.Exception)1036f0ec 65fccbfe System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(System.Web.HttpContext, System.AsyncCallback, System.Object)1036f108 65fd19c5 System.Web.HttpRuntime.ProcessRequestInternal(System.Web.HttpWorkerRequest)1036f13c 65fd16b2 System.Web.HttpRuntime.ProcessRequestNoDemand(System.Web.HttpWorkerRequest)1036f148 65fcfa6d System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr, Int32)1036f358 79f047fd [ContextTransitionFrame: 1036f358] 1036f38c 79f047fd [GCFrame: 1036f38c] 1036f4e8 79f047fd [ComMethodFrame: 1036f4e8] 4.检查代码,看是否有方法使用了锁,进一步证明你的假设。     public DataTable GetFeaturedProducts()         lock (syncobj)             //faking a long running query to the database             Thread.Sleep(5000);              //populate a table with the featured products              DataTable dt = new DataTable();              DataRow dr;      }正如期望中的一样,GetFeaturedProducts()方法设置了一个锁,然后又让线程Sleep了5秒,我们这里只是为了演示一个长时间运行的独占线程的操作而使用sleep来简单模拟实现这个效果。要解决这类问题主要还是靠应用程序的具体实现方式,具体要看期望这个操作的执行时间有多长,并确认是否这个线程阻塞的时间经常要比期望的时间长,然后我们要尽可能只锁住尽量少的代码,以防止有很多请求同时等待一个资源。(原文参考:The resolution here will of course depend largely on the application but it would include looking into how long this operation is supposed to be and finding out if threads are blocking more often than expected, and after review finding ways to make sure we lock around as small a portion of code as possible to avoid having lots of requests waiting for a single resource. )希望你能喜欢这个实验,我将争取在周末以前完成下一个实验(崩溃方面)如果你觉得我遗漏了什么、你的答案跟我的不同(除了线程ID,等待锁的线程个锁等)或者你根本不喜欢这个实验的形式并且你感觉如果能更详细地讲解某些细节就更好些,都请在留言栏里自由回复。-博客园.Debug探索团队  -By Justin/2008年7月18日 6:30:32 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2008/07/18/1242970.html,如需转载请自行联系原作者

6. jTouch – jQuery Cheat Sheet for iPhone [HTML] 7. jQuery 1.4 API Cheat Sheet [HTML, PDF, PNG] 8. jQuery Selectors [PDF] 9. jQuery 1.3 Quick API Reference [ HTML] 10. jQuery UI 1.7 Quick API Reference [ HTML] 11. jQuery 1.3.2 Cheat Sheet [Microsoft Excel (XLS), PDF, PNG] 12. jQuery 1.1.3 Cheat Sheet [Microsoft Excel (XLS), PDF, PNG] 13. jQuery 1.3 Visual Cheat Sheet [PDF] 14. jQuery 1.4.2 Visual Cheat Sheet [JPEG, PDF] 15. jQuery API [HTML] 16. jQuery 1.4 Cheat Sheet [PDF] 17. jQuery cheatsheet Wallpaper 18. jQuery – YUI3 Rosetta Stone [HTML] 19. jQuery 1.2 by Adrien Gibrat [PDF] 20. jQuery 1.3 Cheat Sheet 21. jQuery 1.3 Cheatsheet Wallpaper [1920×1200, 1680×1050 and 1440×900] 22. jQuery 1.3 Visual Cheat Sheet by Antonio Lupetti [PDF] 23. jQuery Selectors Cheatsheet [HTML] 24. jQuery UI – Effects Cheatsheet [HTML] 25. jQuery Validator Cheatsheet – Elegant Code [PDF] 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2010/09/19/1830742.html,如需转载请自行联系原作者

置顶]坚持学习WF文章索引 WF中提供了很多内置的服务,其中工作流计划服务是用来管理工作流实例线程的。默认情况下WF会自动使用DefaultWorkflowSchedulerService服务。使用该服务时在工作流运行时引擎上以异步方式运行工作流实例的线程。 等待运行的工作流存储在 DefaultWorkflowSchedulerService 的内部队列中.当 DefaultWorkflowSchedulerService 要启动工作流时,从 .NET Framework 线程池中获取一个线程并使用此线程运行工作流。 MaxSimultaneousWorkflows 属性确定调度程序服务同一时间允许的并发线程数。 例如,如果限值为 4,则 DefaultWorkflowSchedulerService 将从 .NET Framework 线程池中最多获取 4 个线程来执行工作流。 如果已经运行 4 个工作流,则其他工作项(工作流)将放入队列中,最终在线程可用时执行。 除了使用WF默认提供的,我们还可以手动去加载ManualWorkflowSchedulerService服务。它提供了一个线程服务,该服务允许创建工作流实例的宿主应用程序指定用于运行工作流实例的 Thread。 使用此线程服务,宿主应用程序可在单个 Thread 上运行一个工作流实例(即处于同步模式)。 此模式将阻止宿主应用程序的执行,直到工作流实例进入空闲状态。 随后,只能通过使用此服务的 RunWorkflow 方法执行工作流实例。 下面我们通过MSDN中的一个例子来说明工作流中的线程以及如何使用DefaultWorkflowSchedulerService和ManualWorkflowSchedulerService服务。 一:在该实例中首先开发一个自定义活动WaitForMessageActivity.cs,代码如下: using System; using System.ComponentModel; using System.Threading; using System.Workflow.Activities; using System.Workflow.ComponentModel; using System.Workflow.ComponentModel.Design; using System.Workflow.Runtime; namespace Microsoft.Samples.Workflow.WorkflowThreading     [ToolboxItem(typeof(ActivityToolboxItem))]     public partial class WaitForMessageActivity: Activity         WorkflowQueue workflowQueue;         public WaitForMessageActivity()             InitializeComponent();         protected override void Initialize(IServiceProvider provider)             ThreadMonitor.WriteToConsole(Thread.CurrentThread, "WaitForMessageActivity",                                          "WaitForMessageActivity执行构造函数");             WorkflowQueuingService queuingService = (WorkflowQueuingService)provider.                                          GetService(typeof(WorkflowQueuingService));             this.workflowQueue = queuingService.CreateWorkflowQueue(                                          "WaitForMessageActivityQueue", false);             this.workflowQueue.QueueItemAvailable += this.HandleExternalEvent;         private void HandleExternalEvent(Object sender, QueueEventArgs args)             ThreadMonitor.WriteToConsole(Thread.CurrentThread, "WaitForMessageActivity",                                          "WaitForMessageActivity外部事件处理程序");             object data = this.workflowQueue.Dequeue();             ActivityExecutionContext context = sender as ActivityExecutionContext;             context.CloseActivity();         protected override ActivityExecutionStatus Execute(ActivityExecutionContext context)             ThreadMonitor.WriteToConsole(Thread.CurrentThread, "WaitForMessageActivity",                                          "WaitForMessageActivity等待外部事件处理程序");             return ActivityExecutionStatus.Executing; 二:工作流设计如下图: DelayActivity对工作流的影响我们在前面的文章中有过说明,我们就不管这个了。工作流的代码如下: using System; using System.ComponentModel; using System.Workflow.Activities; using System.Threading; namespace Microsoft.Samples.Workflow.WorkflowThreading public sealed partial class ThreadingWorkflow : SequentialWorkflowActivity private string branchFlag; public ThreadingWorkflow() InitializeComponent(); ThreadMonitor.WriteToConsole(Thread.CurrentThread, "ThreadingWorkflow", "ThreadingWorkflow: 执行构造函数"); public string BranchFlag get { return this.branchFlag;} set { this.branchFlag = value;} private void OnCodeActivity1ExecuteCode(object sender, EventArgs e) ThreadMonitor.WriteToConsole(Thread.CurrentThread, "ThreadingWorkflow", "CodeActivity1的事件处理程序"); private void OnCodeActivity2ExecuteCode(object sender, EventArgs e) ThreadMonitor.WriteToConsole(Thread.CurrentThread, "ThreadingWorkflow", "CodeActivity2的事件处理程序"); private void OnCodeActivity3ExecuteCode(object sender, EventArgs e) ThreadMonitor.WriteToConsole(Thread.CurrentThread, "ThreadingWorkflow", "CodeActivity3的事件处理程序"); private void IfElseBranchActivityCodeCondition(object sender, ConditionalEventArgs e) e.Result = !this.BranchFlag.Equals("Delay", StringComparison.OrdinalIgnoreCase); 三:宿主程序代码如下: using System; using System.Collections.Generic; using System.Threading; using System.Workflow.Runtime; using System.Workflow.Runtime.Hosting; using System.Drawing; namespace Microsoft.Samples.Workflow.WorkflowThreading class Program static AutoResetEvent waitHandle = new AutoResetEvent(false); static AutoResetEvent readyHandle = new AutoResetEvent(false); static WorkflowInstance workflowInstance; static WorkflowRuntime workflowRuntime; static void Main(string[] args) if (args.Length < 2) Console.WriteLine("使用该形式命令行WorkflowThreading.exe [Single | Multi] [Delay | WaitForMessage]"); return; if (!args[0].Equals("Single", StringComparison.OrdinalIgnoreCase) && !args[0].Equals("Multi", StringComparison.OrdinalIgnoreCase)) Console.WriteLine("指定Single 或者Multi 作为第一个命令行参数"); return; if (!args[1].Equals("Delay", StringComparison.OrdinalIgnoreCase) && !args[1].Equals("WaitForMessage", StringComparison.OrdinalIgnoreCase)) Console.WriteLine("指定Delay 或者WaitForMessage 作为第二个命令行参数"); return; ThreadMonitor.Enlist(Thread.CurrentThread, "主机"); Console.ForegroundColor = ConsoleColor.White; using (workflowRuntime = new WorkflowRuntime()) ManualWorkflowSchedulerService scheduler = null; if (args[0].ToString().Equals("Single", StringComparison.OrdinalIgnoreCase)) scheduler = new ManualWorkflowSchedulerService(); workflowRuntime.AddService(scheduler); workflowRuntime.StartRuntime(); workflowRuntime.WorkflowCompleted += OnWorkflowCompleted; workflowRuntime.WorkflowTerminated += OnWorkflowTerminated; workflowRuntime.WorkflowIdled += OnWorkflowIdled; workflowRuntime.WorkflowCreated += OnWorkflowCreated; Type type = typeof(ThreadingWorkflow); Dictionary<string, object> workflowParameters = new Dictionary<string, object>(); workflowParameters.Add("BranchFlag", args[1]); Console.WriteLine("\n--- 开始工作流之前---\n"); workflowInstance = workflowRuntime.CreateWorkflow(type, workflowParameters); workflowInstance.Start(); Console.WriteLine("\n--- 开始工作流之后---\n"); if (scheduler != null) scheduler.RunWorkflow(workflowInstance.InstanceId); readyHandle.WaitOne(); if (args[1].Equals("WaitForMessage", StringComparison.OrdinalIgnoreCase)) workflowInstance.EnqueueItem("WaitForMessageActivityQueue", "Hello", null, null); if (scheduler != null) scheduler.RunWorkflow(workflowInstance.InstanceId); waitHandle.WaitOne(); workflowRuntime.StopRuntime(); static void OnWorkflowCreated(object sender, WorkflowEventArgs e) ThreadMonitor.WriteToConsole(Thread.CurrentThread, "Host", "Host: Processed WorkflowCreated Event"); static void OnWorkflowIdled(object sender, WorkflowEventArgs e) if (workflowRuntime.GetService<ManualWorkflowSchedulerService>() != null) SetReloadWorkflowTimer(); readyHandle.Set(); ThreadMonitor.WriteToConsole(Thread.CurrentThread, "Host", "Host: Processed WorkflowIdle Event"); Console.WriteLine("\n--- 工作流空闲---\n"); static void SetReloadWorkflowTimer() DateTime reloadTime = workflowInstance.GetWorkflowNextTimerExpiration(); if (reloadTime == DateTime.MaxValue) readyHandle.Set(); TimeSpan timeDifference = reloadTime - DateTime.UtcNow + new TimeSpan(0, 0, 0, 0, 1); Timer timer = new System.Threading.Timer( new TimerCallback(ReloadWorkflow), null,timeDifference < TimeSpan.Zero ? TimeSpan.Zero : timeDifference, new TimeSpan(-1)); static void ReloadWorkflow(object state) if (workflowInstance.GetWorkflowNextTimerExpiration() > DateTime.UtcNow) SetReloadWorkflowTimer(); readyHandle.Set(); static void OnWorkflowCompleted(object sender, WorkflowCompletedEventArgs e) ThreadMonitor.WriteToConsole(Thread.CurrentThread, "Host", "Host: Processed WorkflowCompleted Event"); waitHandle.Set(); Console.WriteLine("\n--- 工作流完成---\n"); static void OnWorkflowTerminated(object sender, WorkflowTerminatedEventArgs e) Console.WriteLine(e.Exception.Message); waitHandle.Set(); 在宿主程序我们根据命令行参数的不同来决定是否加载ManualWorkflowSchedulerService ,如果加载了该服务我们 调用该类的RunWorkflow方法来运行工作流实例。 四:ThreadMonitor类的用途是用不同的颜色为每个线程的输出着色。代码如下: using System; using System.Threading; using System.Collections.Generic; using System.Text; namespace Microsoft.Samples.Workflow.WorkflowThreading public static class ThreadMonitor private static int threadCount; private static Dictionary<string, ConsoleColor> threadList = new Dictionary<string, ConsoleColor>(); public static void Enlist(Thread thread, string instanceName) if ((thread.Name == null) || (thread.Name.Length == 0)) thread.Name = string.Format("{0} 线程[{1}]", instanceName, threadCount++); if (!threadList.ContainsKey(thread.Name)) threadList.Add(thread.Name, GetConsoleColor()); public static void WriteToConsole(Thread thread, string instanceName, string message) Enlist(thread, instanceName); WriteToConsole(thread, message); public static void WriteToConsole(Thread thread, string message) if (threadList.ContainsKey(thread.Name)) Console.ForegroundColor = threadList[thread.Name]; Console.WriteLine("{0} --> {1}", thread.Name, message); private static ConsoleColor GetConsoleColor() if ((int)Console.ForegroundColor < 9) return ConsoleColor.White; return (ConsoleColor)(int)Console.ForegroundColor - 1; 五:下图是执行的结果对比,我们可以清晰的看到线程的变化情况。 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双向的所以我们想动态的实现多语言切换很是方便今天我做一个小demo给大家提供一个思路 先看一下效果                                           点击英文  变成英文状态点chinese就会变成中文 源码的下载地址在文章的最下边 多语言用的是资源文件建一个MyLanguage的资源文件再添加一个MyLanguage.en-US的资源文件如果你还想要 其它的语言可自己添加。两个资源文件里写上你要的文本如下图这样,它们的名称是一样的只是值一个是中文一个是英文  下面我们就要开始用Caliburn.Micro的IHandle<T>去实现多语言了 先写一个资源的接口 public interface IResource string GetString(string name); CultureInfo CurrentCulture { set; } public interface IResourceTask void ChangeLanguage(string language); string GetString(string name); event EventHandler LanguageChanged; IResource接口是资源要实现的,GetString(stirng name)方法是得到根据名字得到资源里的值 CurrentCulture是中英文语言转换的 ResourceTask接口是一个管理接口它管理资源的我们通过它去实现 语言转换时把发送广播把页面上的所有文字转换成想要的语言。 再写一个简单的信息接口,也就是我们发送广播时的数据格式 public interface IMessage public class LanguageChangedMessage : IMessage LanguageChangedMessage就是我们要发送广播的数据格式 下面就来实现一下IResourceTask接口 public class ResourceTask : IResourceTask public ResourceTask() System.Data.DataTable _dt = new System.Data.DataTable(); [ImportMany] public IResource[] Resources { get; set; } public void ChangeLanguage(string language) CultureInfo culture = new CultureInfo(language); Thread.CurrentThread.CurrentCulture = culture; Thread.CurrentThread.CurrentUICulture = culture; Resources.Apply(item => item.CurrentCulture = culture); IEventAggregator eventAggregator = IoC.Get<IEventAggregator>(); eventAggregator.Publish(new LanguageChangedMessage()); if (LanguageChanged != null) LanguageChanged(this, null); public event EventHandler LanguageChanged; public string GetString(string name) string str = null; foreach (var resource in Resources) str = resource.GetString(name); if (str != null) break; return str; 通过Resources得到所有export IResource的类 ChangeLanguage(string language)方法里的 Resources.Apply(item => item.CurrentCulture = culture);是把所有实现IResult类的CurrentCulture修改成我们要换成的语言格式 eventAggregator.Publish(new LanguageChangedMessage()); 就是去发送广播,把页面上所有的的文字切换 EventHandler LanguageChanged;事件是如果我们还想切换完语言后做一些事件就可以写在这个事件里 再写一个实现 IResult的类 [Export(typeof(IResource))] [PartCreationPolicy(CreationPolicy.NonShared)] public class MyResource : IResource private ResourceManager stringResource; private CultureInfo culture = new CultureInfo("zh-cn"); public CultureInfo CurrentCulture return culture; culture = value; public MyResource() stringResource = new ResourceManager("WPFMultLanguage.Resource.MyLanguage", typeof(MyResource).Assembly); public string GetString(string name) return stringResource.GetString(name, culture); ResourceManager 可以对我们前边写的两种语言的资源文件的读写 在类初始化的时候我们给出资源文件的路径 在GetString(string name)里我们就可以通过ResourceManager根据当前的culture去读取资源文件里的字符了 接下来的问题就是我们怎么去通过接收广播把页面上把文字切换 我们写一个 XAML 标记扩展类 public class MyResourceExtension : MarkupExtension, INotifyPropertyChanged, IHandle<LanguageChangedMessage> public string Key public string Value if (Key == null) return null; IResourceTask result = IoC.Get<IResourceTask>(); string s = result.GetString(Key); return s; public MyResourceExtension() if (!Execute.InDesignMode) IoC.Get<IEventAggregator>().Subscribe(this); public event PropertyChangedEventHandler PropertyChanged; public void PropertyChanted() if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Value")); public override object ProvideValue(IServiceProvider serviceProvider) IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget; Binding binding = new Binding("Value") { Source = this, Mode = BindingMode.OneWay }; return binding.ProvideValue(serviceProvider) as BindingExpression; public void Handle(LanguageChangedMessage message) PropertyChanted(); 这个类我们要实现MarkupExtension基类这样我们才能把我们的类可以在xmal里标识出来 我们要重写一下ProvideValue(IServiceProvider serviceProvider)方法这里我们是要把Value双向绑定到页面上 这个类实现了还INotifyPropertyChanged和IHandle<LanguageChangedMessage>接口 这两个类能干什么我想你们应该都知道吧一个是用来binging的一个是用来接收消息的 Key就是我资源文件里的名称项 value是资源文件里的值项看一下它的get也可以看来出是通过IResourceTask的getstring把值取出来 接口信息的方法Handle(LanguageChangedMessage message) 只要有消息过来我们就PropertyChanged  Value值这样就可以 把字符切换了, 我们再看一下前台页面是怎么处理的 <Window x:Class="WPFMultLanguage.Views.MyView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:WPFMultLanguage.Command" xmlns:cal="http://www.caliburnproject.org" cal:Message.Attach="[Event Loaded]=[Action LoadEvent($source)]" Title="MyView" Height="300" Width="300"> <StackPanel> <Menu> <MenuItem Header="{local:MyResource Key=英文}" cal:Message.Attach="[Event Click]=[Action ChanguageLanguage('en')]"></MenuItem> <MenuItem Header="{local:MyResource Key=中文}" cal:Message.Attach="[Event Click]=[Action ChanguageLanguage('zh')]"></MenuItem> </Menu> <TextBlock Text="{local:MyResource Key=语言}"/> <Button Content="{local:MyResource Key=你好}"/> <TextBox x:Name="tb_Show" Text="{local:MyResource Key=文本}"></TextBox> <TextBox x:Name="tb_Load" Text="{local:MyResource Key=文本2}"></TextBox> </StackPanel> </Window> xmlns:local="clr-namespace:WPFMultLanguage.Command" 这样是把我们上边写的的xaml扩展类放到页面上 Header="{local:MyResource Key=英文}" 这样每一个控件都会初始化一个MyResourceExtension类都会去订阅IHandle<LanguageChangedMessage>广播 再看一下viewModel namespace WPFMultLanguage.ViewModels [Export(typeof(IShell))] public class MyViewModel :Screen public MyViewModel() public void LoadEvent(object obj) //var res = IoC.Get<IResourceTask>(); //((MyView)GetView()).tb_Load.Text = res.GetString("文本2"); public void ChanguageLanguage(string lan) var res = IoC.Get<IResourceTask>(); switch (lan) case "zh": res.ChangeLanguage("zh-CN"); break; case "en": res.ChangeLanguage("en-US"); break; 源码:WPFMultLanguageDemo.rar  本文转自lpxxn博客园博客,原文链接:http://www.cnblogs.com/li-peng/p/3433974.html,如需转载请自行联系原作者

// 摘要: // 表示一个特性,该特性用于限制调用方对操作方法的访问。 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)] public class AuthorizeAttribute : FilterAttribute, IAuthorizationFilter 但是,美中不足的是,需要微软自带的一些用户验证的东西,比如数据库,配置等等的。 常常我们只需要用SESSION或者Cookies去保存用户登录状态的时候,这岂不是杀鸡用牛刀的感觉? 那么,我们按照微软官方的这个特性,重写一个属于自己的验证特性类就行了。下面是我常用的自己写的一段代码,希望大家用得开心,如果有异议可以自己修改,代码无版权,哈哈,我们只为共享。下面也提供了一个可以直接引用的DLL,需要.NET 4.0 Framework的支持。 下载地址: 点击这里下载 using System.Web.Mvc; namespace System /// <summary> /// 表示需要用户登录才可以使用的特性 /// <para>如果不需要处理用户登录,则请指定AllowAnonymousAttribute属性</para> /// </summary> [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class, Inherited = true, AllowMultiple = true)] public class AuthorizationAttribute : FilterAttribute, IAuthorizationFilter /// <summary> /// 默认构造函数 /// </summary> public AuthorizationAttribute() String authUrl = System.Configuration.ConfigurationManager.AppSettings["AuthUrl"]; String saveKey = System.Configuration.ConfigurationManager.AppSettings["AuthSaveKey"]; String saveType = System.Configuration.ConfigurationManager.AppSettings["AuthSaveType"]; if (String.IsNullOrEmpty(authUrl)) this._AuthUrl = "/User/Login"; this._AuthUrl = authUrl; if (String.IsNullOrEmpty(saveKey)) this._AuthSaveKey = "LoginedUser"; this._AuthSaveKey = saveKey; if (String.IsNullOrEmpty(saveType)) this._AuthSaveType = "Session"; this._AuthSaveType = saveType; /// <summary> /// 构造函数重载 /// </summary> /// <param name="loginUrl">表示没有登录跳转的登录地址</param> public AuthorizationAttribute(String authUrl) : this() this._AuthUrl = authUrl; /// <summary> /// 构造函数重载 /// </summary> /// <param name="loginUrl">表示没有登录跳转的登录地址</param> /// <param name="saveKey">表示登录用来保存登陆信息的键名</param> public AuthorizationAttribute(String authUrl, String saveKey) : this(authUrl) this._AuthSaveKey = saveKey; this._AuthSaveType = "Session"; /// <summary> /// 构造函数重载 /// </summary> /// <param name="authUrl">表示没有登录跳转的登录地址</param> /// <param name="saveKey">表示登录用来保存登陆信息的键名</param> /// <param name="saveType">表示登录用来保存登陆信息的方式</param> public AuthorizationAttribute(String authUrl, String saveKey, String saveType) : this(authUrl, saveKey) this._AuthSaveType = saveType; private String _AuthUrl = String.Empty; /// <summary> /// 获取或者设置一个值,改值表示登录地址 /// <para>如果web.config中未定义AuthUrl的值,则默认为/User/Login</para> /// </summary> public String AuthUrl get { return _AuthUrl.Trim(); } if (String.IsNullOrEmpty(value)) throw new ArgumentNullException("用于验证用户登录信息的登录地址不能为空!"); _AuthUrl = value.Trim(); private String _AuthSaveKey = String.Empty; /// <summary> /// 获取或者设置一个值,改值表示登录用来保存登陆信息的键名 /// <para>如果web.config中未定义AuthSaveKey的值,则默认为LoginedUser</para> /// </summary> public String AuthSaveKey get { return _AuthSaveKey.Trim(); } if (String.IsNullOrEmpty(value)) throw new ArgumentNullException("用于保存登陆信息的键名不能为空!"); this._AuthSaveKey = value.Trim(); private String _AuthSaveType = String.Empty; /// <summary> /// 获取或者设置一个值,该值表示用来保存登陆信息的方式 /// <para>如果web.config中未定义AuthSaveType的值,则默认为Session保存</para> /// </summary> public String AuthSaveType get { return _AuthSaveType.Trim().ToUpper(); } if (String.IsNullOrEmpty(value)) throw new ArgumentNullException("用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】!"); _AuthSaveType = value.Trim(); /// <summary> /// 处理用户登录 /// </summary> /// <param name="filterContext"></param> public void OnAuthorization(AuthorizationContext filterContext) if (filterContext.HttpContext == null) throw new Exception("此特性只适合于Web应用程序使用!"); switch (AuthSaveType) case "SESSION": if (filterContext.HttpContext.Session == null) throw new Exception("服务器Session不可用!"); else if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)) if (filterContext.HttpContext.Session[_AuthSaveKey] == null) filterContext.Result = new RedirectResult(_AuthUrl); break; case "COOKIE": if (!filterContext.ActionDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true) && !filterContext.ActionDescriptor.ControllerDescriptor.IsDefined(typeof(AllowAnonymousAttribute), true)) if (filterContext.HttpContext.Request.Cookies[_AuthSaveKey] == null) filterContext.Result = new RedirectResult(_AuthUrl); break; default: throw new ArgumentNullException("用于保存登陆信息的方式不能为空,只能为【Cookie】或者【Session】!"); 然后在Web.Config文件里面加入下面几句用于配置登陆验证的一些信息: <appSettings> <add key="AuthUrl" value="/User/Login" /> <add key="AuthSaveKey" value="LoginedUser" /> <add key="AuthSaveType" value="Session" /> </appSettings> 使用实例: //...省略引用 namespace MrHuo.Framework.Blog [Authorization]//如果将此特性加在Controller上,那么访问这个Controller里面的方法都需要验证用户登录状态 public class UserController:Controller [AllowAnonymous]//这里是一个特例,有这个特性,表示这个方法不需要验证用户登录状态 public ActionResult Index() //...省略具体代码 //这里的方法需要验证登录状态,以下雷同 public ActionResult Create() //...省略具体代码 分类: ASP.NET,MVC 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/4183721.html,如需转载请自行联系原作者

//这是一个以id,email,age的json字符串   var jdata="[{\"id\":0,\"email\":\"abccd\",\"age\":0},{\"id\":1,\"email\":\"abc1\",\"age\":2}]"; //将这个json字符串,传递到PaperMark.ashx侧处理  $.post("AJAX/PaperMark.ashx", {                             jdata: jdata                         }, function(data, textStatus) { 在PaperMark.ashx我们要引用下面的命名空间 using System.Web.Script.Serialization; using System.Collections.Generic;  string jsonData = context.Request.Form["jdata"];  //取得这个json字符串 //做一个类id,email,age和json格式一致   public class Person         public int id { set; get; }         public String email { set; get; }         public int age { set; get; } //这个一个反序列化的方法,用于返回泛型集合  public static T JSONToObject<T>(string jsonText)         JavaScriptSerializer jss = new JavaScriptSerializer();         return jss.Deserialize<T>(jsonText); //调用上面这个方法,把json字符串传进去,就得到一个对象集合了  List<Person> DataReust = JSONToObject<List<Person>>(jsonData);         for (int i = 0; i < DataReust.Count; i++)             string j = DataReust[i].email; json字符串的构造一定要正确。要不然解析不出来。 为了在js端更为方便的构造出正确的json对象,我做了一些函数用于生成json字符串              var jstr = "";               var jsData = "[";   //这个就是最后生成的json字符串               function AddJsonItemStart() {                   jstr = "";               //vtype==int的时候不加引号               function AddJsonItem(name, val, vtype) {                   if (jstr == "") {                       //为整型的情况下面                       if (vtype == "int") {                           jstr = "{\"" + name + "\":" + val + ",";                       else {                           //为字符串的情况下面                           jstr = "{\"" + name + "\":\"" + val + "\",";                   else {                       if (vtype == "int") {                           jstr = jstr + "\"" + name + "\":" + val + ",";                       else {                           jstr = jstr + "\"" + name + "\":\"" + val + "\",";               function AddJsonItemOK() {                   jstr = jstr.substring(0, jstr.length - 1) + "},";                   jsData = jsData + jstr;               function AddJsonEnd() {                   jsData = jsData.substring(0, jsData.length - 1) + "]";            使用方法:                   AddJsonItemStart();                   AddJsonItem("id", 1, "int");                   AddJsonItem("email", "abc", "string");                   AddJsonItem("age", 5, "int");                   AddJsonItemOK();                   AddJsonItemStart();                   AddJsonItem("id", 2, "int");                   AddJsonItem("email", "cef", "string");                   AddJsonItem("age", 6, "int");                   AddJsonItemOK();                   AddJsonEnd(); 分类: ASP.NET 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/3175252.html,如需转载请自行联系原作者

Windows 2008 IIS7.5中创建独立账号的FTP站点图文教程

Windows 2008上的IIS7.5,FTP功能已经非常强大了,完全不下于Serv-U这样的第三方软件。本文小编就介绍在IIS7.5上配置独立账号的FTP站点。 1、创建Windows账号 右击点击“我的电脑”,选择“管理”打开服务器管理的控制台。展开“服务器管理器”,一路展开“配置”、“本地用户和组”,点“用户”项。然后在右边空白处点右键,选择“新用户”将打开新建用户的对话框。在此输入用户名test1、密码,并设置密码永不过期,用户下次登录不用修改密码。 双击新增加的用户,将打开用户属性的对话框。点击“隶属于”选项卡,设置test1这个账号属于guests组,并把原来的users组删除掉。 2、创建目录 在D:\wwwroot\目录下创建一个名为test1的目录,作为test1这个用户登录ftp的主目录。 给D:\wwwroot\test1目录添加一个test1用户的可读、可写、可修改的权限,这样用户登录上来才能上传、下载、删除文件。 3、在IIS添加FTP站点 运行“inetmgr”打开IIS控制台,右键点击“网站”,选择“添加FTP站点”。具体的配置项及其值如下:FTP站点名称:test1物理路径:D:\wwwroot\test1IP地址:全部未分配端口:21启用虚拟主机名:不勾自动启动FTP站点:勾SSL:无本文转自左正博客园博客,原文链接:,如需转载请自行联系原作者身份验证:基本允许访问:指定用户,test1权限:读取、写入4、客户端连接使用FlashFXP这样的工具来测试一下,IP地址就是服务器的IP,端口我们刚才配置的21,用户名和密码就是test1用户的账号和密码。是不是很简单呢?除了test1外,你还可以配置test2、test3等等,实现一个用户、一个目录、一个ftp站点。这个跟IIS建独立站点貌似极其相似哈!关于Windows 2008的IIS7.5上配置独立用户的FTP站点,洪哥就介绍这么多,希望对大家有所帮助,谢谢。

RequiredFieldValidator 根据group组来触发验证

今天在开发过程中遇到了这样一个问题 在这个用户添加界面中,我使用了多个验证控件RequiredFieldValidator,分别控制用户名密码。在默认情况下,当单击“检查用户名”时,密码的验证控件也被触发。这种效果不是我预期的。我需要单独对用户名进行为输入验证。当检查通过时,再对密码是否输入是否输入一致进行验证。 说明:在ASP.NET 1.1中除了hack code没有更好的办法。ASP.NET 2.0中给所有的validator控件和按钮(button、linkbutton等等)增加了ValidatorGroup属性,就可以轻松地解决这个问题。如果在页面中有一个TextBox并且紧挨着他有一个RequiredFieldValidator 和Button控件,可以将RequiredFieldValidator和Button的ValidationGroup属性设置成一样的值从而使得点 击button时只触发这个RequiredFieldValidator的validor,任何没有定义在ValidationGroup内的其他的 validator都会被忽略。 解决方法如下:如图只需将ValidationGroup设置为同一组即可。 分类: ASP.NET 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/3850840.html,如需转载请自行联系原作者

.Net魔法堂:史上最全的ActiveX开发教程——ActiveX与JS间交互篇

经过上几篇的学习,现在我们已经掌握了ActiveX的整个开发过程,但要发挥ActiveX的真正威力,必须依靠JS。下面一起来学习吧! 二、JS调用ActiveX方法                     只需在UserControl子类中(即自定义的ActiveX控件中),编写公共方法即可。 [Guid("0203DABD-51B8-4E8E-A1EB-156950EE1668")] public partial class Uploader : UserControl, IObjectSafety public Uploader(){   InitializeComponent(); // 被JS调用的ActiveX方法 public void SayHi(msg){ MessageBox.show(msg); // 注意:object必须要写成<object></object>才能通过document.getElementById来获取 <object classid="clsid:xxxxxxxxxx" id="ax"></object> <script type="text/javascript">   document.getElementById('ax').SayHi('Test');// 调用ActiveX方法 </script> 三、ActiveX调用JS方法                         1. 引入`Microsoft.mshtml`程序集,该程序集位于`C:\Program Files\Microsoft.NET\Primary Interop Assemblies\Microsoft.mshtml.dll`   2. 实现COM类`IOleClientSite` [ComImport, Guid("00000118-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleClientSite void SaveObject(); void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk); void GetContainer(out IOleContainer ppContainer); void ShowObject(); void OnShowWindow(bool fShow); void RequestNewObjectLayout();   3. 实现COM类`IOleContainer` [ComImport, Guid("0000011B-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)] public interface IOleContainer void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags, [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum); void ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] object pbc, [In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName, [Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten, [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut); void LockContainer([In, MarshalAs(UnmanagedType.I4)] int fLock);   4. 在用户控件中调用JS方法 在MyUserControl.cs中 #region 调用js函数 private Type typeIOleObject = null; private IOleClientSite oleClientSite = null; private IOleContainer pObj = null; /// <summary> /// 调用JS函数 /// </summary> /// <param name="fnName">js函数名</param> /// <param name="args">入参</param> protected void CallJS(string fnName, params object[] args) if (typeIOleObject == null) typeIOleObject = this.GetType().GetInterface("IOleObject", true); object tmpOldClientSite = typeIOleObject.InvokeMember("GetClientSite", BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, this, null); oleClientSite = tmpOldClientSite as IOleClientSite; oleClientSite.GetContainer(out pObj); //获取页面的Script集合 IHTMLDocument pDoc2 = (IHTMLDocument)pObj; object script = pDoc2.Script; //调用JavaScript方法OnScaned并传递参数,因为此方法可能并没有在页面中实现,所以要进行异常处理 script.GetType().InvokeMember(fnName, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, script, args); catch { } #endregion 五、踩过的坑                             1. 若在IE9下无法加载ActiveX控件    检查是否为64位的IE9。32位的ActiveX控件不能在64位的IE上使用。(通过“任务管理器”查看进程名称,若为浏览器进程名称后跟32就是32位的)   《.Net魔法堂:史上最全的ActiveX开发教程》系列总算整理完了,起个博眼球的标题,希望系列的内容不会让大家失望啦。谢谢收看,哈哈!   尊重原创,转载请注明来自:http://www.cnblogs.com/fsjohnhuang/p/3823687.html ^_^肥仔John 如果您觉得本文的内容有趣就扫一下吧!捐赠互勉! 本文转自^_^肥仔John博客园博客,原文链接:http://www.cnblogs.com/fsjohnhuang/p/3823687.html,如需转载请自行联系原作者

处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表

IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决办法 IIS上部署MVC网站,打开后ExtensionlessUrlHandler-Integrated-4.0解决方法 IIS上部署MVC网站,打开后500错误:处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表中有一个错误模块“ManagedPipelineHandler”   解决方法如下: 以管理员运行下面的命令注册: 32位机器: C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i 64位机器: C:\Windows\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -i 分类: ASP.NET 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/4453735.html,如需转载请自行联系原作者

new Array(element0, element1, ..., elementn); 参数 size 是期望的数组元素个数。返回的数组,length 字段将被设为 size 的值。 参数 element ..., elementn 是参数列表。当使用这些参数来调用构造函数 Array() 时,新创建的数组的元素就会被初始化为这些值。它的 length 字段也会被设置为参数的个数。 返回新创建并被初始化了的数组。 如果调用构造函数 Array() 时没有使用参数,那么返回的数组为空,length 字段为 0。 当调用构造函数时只传递给它一个数字参数,该构造函数将返回具有指定个数、元素为 undefined 的数组。 当其他参数调用 Array() 时,该构造函数将用参数指定的值初始化数组。 当把构造函数作为函数调用,不使用 new 运算符时,它的行为与使用 new 运算符调用它时的行为完全一样。 Array 对象属性 constructor 返回对创建此对象的数组函数的引用。 length 设置或返回数组中元素的数目。 prototype 使您有能力向对象添加属性和方法。

.Net魔法堂:log4net详解

提供一个记录日志的框架,可以将日志信息记录到文件、控制台、Windows事件日志和数据库(MSSQL、Acess、Oracle、DB2和SQLite等)。 二、先看看示例,感受一下吧                     config配置文件 <?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> </configSections> <log4net> <!-- 定义日志的输出媒介 --> <root> <appender-ref ref="ConsoleAppender"/> <appender-ref ref="R"/> </root> <!-- 定义输出到控制台 --> <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline"/> </layout> </appender> <!-- 定义输出到日志文件 --> <appender name="R" type="log4net.Appender.FileAppender" rollingStyle="Date" datePattern="yyyyMMdd-HH:mm:ss"> <file value="logs/log.txt"></file> <appendToFile value="true"></appendToFile> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%-d{yyyy-MM-dd HH\:mm\:ss} [%L] [%c]-[%p] %m%n"></conversionPattern> </layout> </appender> </log4net> </configuration> * 指定log4net使用.config文件来读取配置信息 * 若为Winform(假定程序为Demo.exe), 那么配置文件则为Demo.exe.config * 若为Webform,则为web.config [assembly:log4net.Config.XmlConfigurator(Watch=true)] namespace Demo{ public class MainClass{ public static void Main(String[] args){ ILog log = log4net.LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); log.Error("error", new Exception("there is an exception")); log.Fatal("fatal", new Exception("there is a deadly exception occurs")); log.Info("info"); log.Debug("debug"); log.Warn("warn"); Console.Read(); 三、框架的核心组件                           1. Appender   作用:用于定义日志信息的输出介质(文件、控制台、Windows事件日志和数据库(MSSQL、Acess、Oracle、DB2和SQLite等))内置的Appdner组件:      ConsoleAppender ,输出介质为控制台        FileAppender     ,输出介质为文件,示例如下 <appender name="FileAppender" type="log4net.Appender.FileAppender" file="logs/log.txt" appendToFile="true"> <layout type="log4net.Layout.PatternLayout"> .......... </layout> </appender>             RollingFileAppender ,将日志以回滚文件的形式写入文件中。可以指定文件最大容量,当超过就生成一个新文件来记录,且可以指定最多生成日志文件数量,当超过时则覆盖从第一个日志文件开始循环覆盖。 <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" file="logs/log.txt" appendToFile="true" rollingStyle="Size" maxSizeRollBackups="10" maximumFileSize="100KB" staticLogFileName="true"> <layout type="log4net.Layout.PatternLayout"> .......... </layout> </appender> <appender name="RollingFileAppender" type="log4net.Appender.RollingFileAppender" file="logs/log.txt" appendToFile="true" rollingStyle="Date" datePattern="yyyyMMdd"> <layout type="log4net.Layout.PatternLayout"> .......... </layout> </appender>            EventLogAppender ,输出介质为系统日志            AdoNetAppender    ,输出介质为数据库,示例如下  View Code             自定义Appender时,需要继承 log4net.Appender.AppenderSkeleton   2. Layout      作用:定义向用户显示最终的经格式化的输出信息。     注意:一个Appender对象仅能对应一个Layout对象      内容的Layout组件:      PatternLayout ,用户自定义格式,内置参数如下 %m(message),输出的日志消息%n(newline),换行%d(datetime),输出当前语句运行的时刻%r(runtime),输出程序从运行到当前语句时消耗的毫秒数%t(thread id),输出当前语句运行的线程ID%p(level),输出日志级别(日志事件)%c(class),输出当前语句所在的对象名称%M(method),输出当前语句所在的方法名称%f(file),输出当前语句所在的文件名称%L(line),输出当前语句位于所在的文件中的行号%l(location),输出当前语句位于的全限定类名,以及源文件和行号%数字,表示该项的最小长度,如果不够则在左边用空格填充。如:%5p,表示输出日志级别,且长度最小为5个字符%-数字,表示该项的最小长度,如果不够则在右边用空格填充。如:%-5p,表示输出日志级别,且长度最小为5个字符%.数字,表示该项的最大长度,如果超出则截断%数字.数字,表示该项的必须位于最小和最大长度之间,如果超出则截断, 不够则用空格填充               最佳实践: %-d{yyyy-MM-dd HH\:mm\:ss} [%L] [%c]-[%p] %m%n                SimpleLayout                ExceptionLayout ,输出时包含Message和Trace信息。Logger方法必须传入Exception对象,否则什么都不输出。XmlLayout,中文会有问题。               自定义Layout时,需要继承 log4net.Layout.LayoutSkeleton    3. Appender Filter   作用:默认情况下Appender对象会将所有日志信息都输出到相应的介质中,通过Appender Filter对象(命令空间:log4net.Filter)可以按照不同的标准过滤日志事件或内容。内置的Filter组件:      DenyAllFilter ,阻止所有的日志事件被记录          LevelMatchFilter ,只有指定等级的日志事件才被记录          LevelRangeFilter ,日志等级在指定范围内的事件才被记录          LoggerMatchFilter , Logger名称匹配才被记录          PropertyFilter ,消息匹配指定的属性值才被记录          StringMatchFilter ,消息匹配指定的字符串才被记录   4. Logger     作用:直接与应用交互的组件,用于触发日志事件 级别(日志事件) FATAL ERROR DEBUG   5. Object Render    作用:输出根据Layout格式化的日志消息。Render必须实现log4net.ObjectRender.IObjectRender接口    6. Repository    作用:负责日志对象组织结构的维护。对于非框架扩展者,几乎不会用到该组件。 四、配置方式                              1. 代码中配置     通过 log4net.Config.BasicConfigurator.Configure 配置根日志且只能配置根日志而已。 // 和PatternLayout一起使用FileAppender log4net.Config.BasicConfigurator.Configure( new log4net.Appender.FileAppender( new log4net.Layout.PatternLayout("%d [%t]%-5p %c [%x] - %m%n"),"testfile.log")); // using a FileAppender with an XMLLayout log4net.Config.BasicConfigurator.Configure( new log4net.Appender.FileAppender( new log4net.Layout.XMLLayout(),"testfile.xml")); // using a ConsoleAppender with a PatternLayout log4net.Config.BasicConfigurator.Configure( new log4net.Appender.ConsoleAppender( new log4net.Layout.PatternLayout("%d [%t] %-5p %c - %m%n"))); // using a ConsoleAppender with a SimpleLayout log4net.Config.BasicConfigurator.Configure( new log4net.Appender.ConsoleAppender(new log4net.Layout.SimpleLayout()));   2. 配置文件(推荐使用)     log4net框架会在 AppDomain.CurrentDomain.BaseDirectory 指向的目录路径下查找配置文件。     在config文件中配置             在<configuration>节点下添加<configSections>节点 <configSections> <section name="log4net" type="System.Configuration.IgnoreSectionHandler"/> </configSections>             只有添加上述节点,log4net.dll才能读取config文件下<log4net>节点下配置信息      根日志<root>节点             框架中所有日志对象都是根日志的后代,因此日志对象若没有显式配置时则会使用根日志的配置信息。 <root> <!-- level节点用于定义处理哪个级别的日志事件,缺省值为DEBUG --> <level>INFO</level> <!-- appender-ref节点用于定义日志对象所使用的Appender对象 --> <appender-ref ref="appender节点的name属性值"/> </root>     日志对象<logger>节点       显式配置日志对象。 <!-- additivity特性设置为false时,日志对象将不继承根日志的appender-ref节点信息。缺省值为true --> <logger name="test.Logging" additivity="false"> <!-- 覆盖根日志的level设置 --> <level value="WARN"/> </logger>            .cs文件中的相应的调用方式 log4net.LogManager.GetLogger("test.Logging");    Appender对象<appender>节点 <appender name="appender1" type="log4net.Appender.FileAppender"> <layout type="log4net.Laytout.PatternLayout"> <conversionPattern value=".........."/> </layout> <filter type="log4net.Filter.LevelRangeFilter" levelMin="DEBUG" levelMax="WARN"> </filter> </appender> 五、关联配置文件                               每个可独立执行的程序集均可以关联自己的配置文件。(组件库就使用调用者的配置文件好了)    在 AssemblyInfo.cs文件 中添加 [assembly:log4net.Config.DOMConfigurator([ConfigFile="配置文件名"|ConfigFileExtension="编译后配置文件的扩展名"][Watch=true/false]) 参数说明:  ConfigFile :指定配置文件含扩展名的路径,如果为相对路径则以AppDomain.CurrentDomain.BaseDirectory为当前路径;  ConfigFileExtension :若程序编译后配置文件使用了不同的扩展名,则通过该属性指定,默认值为config,配置文件的最终名称为"应用程序名.exe.config";                                          注意:ConfigFile和ConfigFileExtension属性是互斥的,仅能设置其中一个  Watch :设置是否需要运行时监视文件的修改、重命名和删除等事件,若设置为true,则使用FileSystemWatcher来监视配置文件。 六、输出日志的优化方式                           * 由于触发日志事件时,会检查日志对象的级别是否满足日志事件的级别 * 先检测日志对象的级别,才触发日志事件 if (log.IsDebugEnabled) log.Debug("message.....");     现在我们就不再糊里糊涂地调用log4net了,建议具体使用时再查阅API文档!     尊重原创,转载请注明来自: http://www.cnblogs.com/fsjohnhuang/p/3991218.html  ^_^肥仔John http://www.cnblogs.com/jams742003/archive/2009/12/10/1620861.html http://zhoufoxcn.blog.51cto.com/792419/429988 如果您觉得本文的内容有趣就扫一下吧!捐赠互勉! 本文转自^_^肥仔John博客园博客,原文链接:http://www.cnblogs.com/fsjohnhuang/p/3991218.html,如需转载请自行联系原作者

•MVC(Model-View-Controller)用于表示一种软件架构模式.它把软件系统分为三个基本部分: –模型(Model) •引用系统数据,管理系统功能并通知View更改用户操作。 –视图(View) •就是用户接口,用于显示数据 –控制器(Controller) •将用户操作映射到Model,并操作视图   A.2,3-Tier Architecture(三层架构) B.1,WebForm Ø采用事件驱动模式来控制应用程序请求,由大量服务器控件支持 Ø采用页面控制机制,可以为单个页面添加事件处理函数。 Ø使用view state和服务器端控件,使管理页面状态信息更加轻松。 Ø对人数较少的想使用服务器端控件的开发团队,使用起来更加方便 Ø开发起来比mvc模式要轻松简单一些适用于快速开发 B.2,MVC Ø通过model、view和controller有效的简化了复杂的架构,体现了很好的隔离原则,使得复杂项目更加容易维护。 Ø一切皆可测试,对单元测试的支持更加出色 Ø一切皆可扩展:ViewEngine、HtmlHelper还有Filter。 Ø适用于大型架构开发,在团队开发模式下表现更出众。 Ø强类型View实现,更安全、更可靠、更高效。 Ø开源,意味着更好的控制和理解。 Ø没有View State,没有Server Control,可以更方便的控制应用程序的行为 Ø应用程序通过controller来控制程序请求,可以提供丰富的url重写。 本文转自ylbtech博客园博客,原文链接:http://www.cnblogs.com/ylbtech/p/4175608.html,如需转载请自行联系原作者

WF中的跟踪服务(5):SqlTrackingService 的数据维护

相关文章:WF中的跟踪服务(4):使用跟踪配置文件WF中的跟踪服务(3):使用SqlTrackingService跟踪规则WF中的跟踪服务(2):使用SqlTrackingServiceWF中的跟踪服务(1):Sql跟踪数据库表,视图,存储过程等相关说明 WF框架中内置的SqlTrackingService服务提供了数据维护的功能,可以将跟踪数据库中的信息移动到指定的分区中。利用该功能我们可以有效的管理这些不断增长的跟踪数据,使得维护和数据的分析更容易。 WF 提供两种分区的方案,自动和手动两种方式。默认情况下SqlTrackingService 的分区功能是没有启用的,要想启用需要将SqlTrackingService 的PartitionOnCompletion 属性设置为 true,如果启用了分区,则会为跟踪数据定期创建一组新的表,以便能够将旧数据存档并将其从主数据库中删除,而不会影响当前运行的应用程序。 在启用分区的情况下,将仍然在原始表中创建跟踪数据,但随后当工作流完成时,这些数据将被移到分区表中。 1.自动的方式 该方式不会影响应用程序的正常运行。 分区是在每个工作流实例完成时执行的。 由于跟踪工作流实例而生成的记录会添加到常规跟踪表中,直到工作流实例完成。 届时,这些记录会移至分区表中。 当启用了分区时,会定期为跟踪数据创建一组新的表。 已完成的工作流实例的跟踪数据会移至这些新的分区中,同时不会中断当前正在运行的应用程序。默认的间隔是每月的,如果你要改变你就使用SetPartitionInterval存储过程。该存储过程接收一个单独的参数表示新的间隔,d(daily),w(weekly),m(monthly),and y(yearly)这几个值。该值存储在TrackingPartitionInterval表中。表 vw_TrackingPartitionSetName 包含有关分区集名称的信息,包括 Name 、CreatedDateTime、EndDateTime 以及 PartitionInterval。 2.手动的方式 手动的方式是在应用程序停止的时候进行的,使用PartitionCompletedWorkflowInstances 存储过程将工作流实例从实时表中插入的跟踪数据移到分区表中。这两种方式各有优缺点。 自动的会影响性能,特别是数据量很大的时候。 如果你不想有性能的损失,就手动做,默认情况PartitonOnCompletion属性就是false的,一般在你停机时候来做分区。 当你不再需要这个分区的时候,你有两种选择,一种是分离,一种是删除。使用DetachPartiton存储过程,就逻辑上从标准的视图中移除了分区。实际上内部执行的是RebulidPartitonViews存储过程来更新视图。就是说当你分离这些分区的时候,这些表并没有删除。使用DropPartiton存储过程物理上删除表。这两个存储过程都接收一个分区名称和分区id,你可以通过查询vw_TrackingPartitonSetName来得到这些值。 1.我们将相关的操作封装一个类SqlDataMaintenanceHelper,代码如下: public class SqlDataMaintenanceHelper public const string strConn = "Initial Catalog=WorkflowTracking;Data Source=localhost; Integrated Security=SSPI;"; //设置分区时间周期 public static void SetPartitionInterval(char interval) using (SqlConnection conn = new SqlConnection(strConn)) SqlCommand command = new SqlCommand("SetPartitionInterval", conn); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add( new SqlParameter("@Interval", interval)); command.Connection.Open(); command.ExecuteNonQuery(); catch (SqlException e) Console.WriteLine("SqlException in SetPartitionInterval: {0}", e.Message); //删除分区 public static void DropPartition(Int32 partitionId) using (SqlConnection conn = new SqlConnection(strConn)) SqlCommand command= new SqlCommand("DropPartition", conn); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@PartitionName", null)); command.Parameters.Add(new SqlParameter("@PartitionId", partitionId)); command.Connection.Open(); command.ExecuteNonQuery(); Console.WriteLine("Partition {0} dropped", partitionId); catch (SqlException e) Console.WriteLine("SqlException in DropPartition: {0}", e.Message); public static void DetachPartition(Int32 partitionId) using (SqlConnection conn = new SqlConnection(strConn)) SqlCommand command = new SqlCommand("DetachPartition", conn); command.CommandType = CommandType.StoredProcedure; command.Parameters.Add(new SqlParameter("@PartitionName", null)); command.Parameters.Add(new SqlParameter("@PartitionId", partitionId)); command.Connection.Open(); command.ExecuteNonQuery(); Console.WriteLine("Partition {0} dropped", partitionId); catch (SqlException e) Console.WriteLine("SqlException in DropPartition: {0}", e.Message); //手动执行分区 public static void PartitionCompletedInstances() using (SqlConnection conn= new SqlConnection(strConn)) SqlCommand command = new SqlCommand("PartitionCompletedWorkflowInstances", conn); command.CommandType = CommandType.StoredProcedure; command.Connection.Open(); command.ExecuteNonQuery(); Console.WriteLine("Partitioning of workflows completed"); catch (SqlException e) Console.WriteLine("SqlException in PartitionCompletedInstances: {0}", e.Message); //显示分区信息 public static void ShowAllPartitions() using (SqlConnection conn= new SqlConnection(strConn)) SqlCommand command = new SqlCommand(@"SELECT * from vw_TrackingPartitionSetName ORDER BY PartitionId", conn); command.Connection.Open(); Console.WriteLine("--显示分区相关信息--"); Console.WriteLine("{0,-4} {1,-13} {2,-22} {3,-20} {4,-4}", "Id", "Name", "CreatedDateTime", "EndDateTime", "PartitionInterval"); using (SqlDataReader reader = command.ExecuteReader()) while (reader.Read()) Console.WriteLine("{0,-4} {1,-13} {2,-22} {3,-20} {4,-4}", reader["PartitionId"], reader["Name"], reader["CreatedDateTime"], reader["EndDateTime"], reader["PartitionInterval"]); reader.Close(); Console.WriteLine("--显示分区相关信息完成--"); Console.WriteLine(); catch (SqlException e) Console.WriteLine("SqlException in DisplayAllPartitions: {0}", e.Message); //显示分区表信息 public static void ShowPartitionTableInfo() using (SqlConnection conn = new SqlConnection(strConn)) SqlCommand command = new SqlCommand("declare @trackingName varchar(255) select @trackingName = Name from TrackingPartitionSetName " +"select name from sysobjects where name like '%' + @trackingName", conn); command.Connection.Open(); Console.WriteLine("--显示分区表相关信息--"); using (SqlDataReader reader = command.ExecuteReader()) while (reader.Read()) Console.WriteLine(reader[0]); reader.Close(); Console.WriteLine("--显示分区表相关信息完成--"); Console.WriteLine(); catch (SqlException e) Console.WriteLine("SqlException in ShowPartitionTableInformation: {0}", e.Message); 2.我们建立一个最简单的工作流,只放一个CodeActivity,宿主程序中我们加载SqlTrackingService服务, 并使用上面的类来显示相关信息,代码如下: class Program static void Main(string[] args) using(WorkflowRuntime workflowRuntime = new WorkflowRuntime()) SqlTrackingService sts = new SqlTrackingService(SqlDataMaintenanceHelper.strConn); sts.PartitionOnCompletion = false; SqlDataMaintenanceHelper.SetPartitionInterval('d'); workflowRuntime.AddService(sts); AutoResetEvent waitHandle = new AutoResetEvent(false); workflowRuntime.WorkflowCompleted += delegate(object sender, WorkflowCompletedEventArgs e){waitHandle.Set();}; workflowRuntime.WorkflowTerminated += delegate(object sender, WorkflowTerminatedEventArgs e) Console.WriteLine(e.Exception.Message); waitHandle.Set(); WorkflowInstance instance = workflowRuntime.CreateWorkflow(typeof(CaryDataMTDemo.Workflow1)); Console.WriteLine("--工作流开始执行--"); instance.Start(); waitHandle.WaitOne(); Console.WriteLine("--工作流执行结束--"); Console.WriteLine(); SqlDataMaintenanceHelper.ShowAllPartitions(); SqlDataMaintenanceHelper.ShowPartitionTableInfo(); 3.程序执行的结果如下: 我们可以看看数据库中表和视图的变化,如下图: 4.如果你删除当前的分区时,会报下面的错误: SqlException in DropPartition: DetachPartition 失败 - 分区正处于 Activity 状态或处于翻转期。 这是因为你不能使当前分区处于非活动状态,因为如果可以的话,你就没有办法在工作流实例完成的时候将跟踪数据转移到分区中了。你只能分离或删除非活动的分区。当分区的间隔过期后就会产生新的分区,这个时候新的分区就成为了活动分区,原来的就变为非活动分区,这个时候就可以删除了。 本文转自生鱼片博客园博客,原文链接:http://www.cnblogs.com/carysun/archive/2008/11/30/SqlDataMaintenance.html,如需转载请自行联系原作者

JSP中的表单 <form action="login.action" method="post">     用户名:<input type="text" name="username"/>    <br/>     密码:  <input type="password" name="password" /> <br/>     <input type="submit" value="登陆" /> </form> Action中的属性                                                         public class LoginAction extends ActionSupport {     private String username;     private String password;     public String getUsername() {        return username;     public void setUsername(String username) {        this.username = username;     public String getPassword() {        return password;     public void setPassword(String password) {        this.password = password;     public String execute(){        if( username.equalsIgnoreCase("aaa")&&password.equals("aaaaaa")){            return SUCCESS;        else{            return ERROR; 2.       使用一个VO类 在表单中提交的属性名改为user.username <form action="login.action" method="post">        用户名:<input type="text" name="user.username"/>  <br/>        密码:  <input type="password" name="user.password" /> <br/>        <input type="submit" value="登陆" />     </form> LoginAction中的属性改为user public class LoginAction extends ActionSupport{     private User user;     public User getUser() {        return user;     public void setUser(User user) {        this.user = user;     public String execute(){        if( user.getUsername().equalsIgnoreCase("aaa")&&user.getPassword().equals("aaaaaa")){            return SUCCESS;        else{            return ERROR; 3.       使用Struts2中的ModelDriven数据模式 Action类要实现一个泛型接口,前台表单与1相同 public class LoginAction extends ActionSupport implements ModelDriven<User> {     private User user = new User();     public String execute(){        if( user.getUsername().equalsIgnoreCase("aaa")&&user.getPassword().equals("aaaaaa")){            return SUCCESS;        else{            return ERROR;     public User getModel() {        return user; 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/6366178.html,如需转载请自行联系原作者

[Share]Top 200 Blogs for Developers (Q3 2009)

And some other people are also doing well on this new edition of the Top 200 Blogs for Developers. Jeff Atwood has replaced Scott Hanselman, meaning that he now has the #1 Development Blog in the world!And look at Scott Berkun, shooting up to the #3 spot. How does he dothat? He’s not even a developer! Plus, we have no less than 21 new entries on the list. I’m sure there’s something for everyone here. Like before, I created this list using Google PageRank, Technorati Authority, Alexa Rank, Google links, Twitter Grader Rank, AideRSS PostRank and theMongolian Stock Exchange. (For more information see: How to Make a Top Blog List.) And like before, I hope you will tweet, digg, bookmark, and comment the hell out of this article! It was, as usual, a tremendous amount of work. I have updated a significant number of Twitter names in this list, and I’m confident that this is now the best list of software development twitterers in the world. Use it to connect with all soft dev gurus and celebrities. And don’t forget to follow me as well: @jurgenappelo. I try no to be boring. Usually. If you want to import all feeds in your reader, grab the OPML file here. (Note: The list does not contain blogs wherethe authors exclusively write about specific tools or technologies,like .NET, or Java. Every blog should have at least _some_ content thatis of interest to every developer regardless of technical background.) Author Twitter Coding Horror Jeff Atwood codinghorror Scott Hanselman's Computer Zen Scott Hanselman shanselman The Berkun Blog Scott Berkun berkun Lambda the Ultimate (various) UIE Brain Sparks Jared Spool jmspool Bokardo: Social Design Joshua Porter bokardo Dr. Dobb's CodeTalk (various) Stack Overflow Jeff Atwood Joel on Software Joel Spolsky spolsky CodeBetter.Com (various) codebetter Martin Fowler's Bliki Martin Fowler martinfowler Raible Designs Matt Raible mraible Artima Weblogs (various) Signal vs. Noise (various) 37signals Object Mentor Blog (various) Dare Obasanjo aka Carnage4Life Dare Obasanjo carnage4life Jon Udell Jon Udell judell The Daily WTF (various) dailywtf Rands in Repose Michael Lopp rands NOOP.NL Jurgen Appelo jurgenappelo A Software Insiders Point of View R "Ray" Wang rwang0 Regular Geek Rob Diana robdiana Project Shrink Bas de Baar projectshrink Atlassian Developer Blog (various) atlassian The Endeavour John D. Cook JohnDCook High Scalability Todd Hoff Jeffrey Palermo (.com) Jeffrey Palermo jeffreypalermo Google Testing Blog (various) Contrast | The Blog (various) Leading Agile Mike Cottmeyer mcottmeyer Alex Payne Alex Payne Agile Management Blog David Anderson agilemanager It's Just a Bunch of Stuff That Happens Eric Burke burke_eric Pure Danger Tech Alex Miller puredanger Blankenthoughts Jeff Blankenburg jblankenburg Chris Spagnuolo's EdgeHopper Chris Spagnuolo chrisspagnuolo Elegant Code (various) elegantcode secretGeek Leon Bambrick secretgeek Pathfinder (various) Evolving Web Jim Benson ourfounder CodeThinked Justin Etheredge justinetheredge Ted Leung on the Air Ted Leung twleung Agile Blog (various) agileblog Alistair Cockburn Alistair Cockburn totheralistair Managing Product Development Johanna Rothman johannarothman Software application development Adrian Bridgwater abridgwater Devlicio.us (various) devlicious Aligning Technology, Strategy, People & Projects Eric Brown ericdbrown Business of Software Blog Neil Davidson neildavidson Agile Software Development Made Easy Kelly Waters allaboutagile Interoperability Happens Ted Neward tedneward The Cutter Blog (various) cuttertweets Testing at the Edge of Chaos Matthew Heusser mheusser James Shore: The Art of Agile James Shore jamesshore Agile Software Development (various) agileartem JUnit Max Kent Beck kentbeck J.D. Meier's Blog J.D. Meier Shanine.com / omar / Omar Shahine omarshahine Otaku, Cedric's Weblog Cedric cbeust {Codesqueeze} Max Pool mpool James Bach’s Blog James Bach jamesmarcusbach PMThink! (various) Meme Agora Neal Ford neal4d Mark Needham Mark Needham markhneedham Better Projects Craig Brown Exploration Through Example Brian Marick marick Scrum Log Jeff Sutherland jeffsutherland Relevance Blog (various) /\ndy Andy Hunt pragmaticandy Mike Cohn's Blog: Succeeding with Agile Mike Cohn mikewcohn The Third Bit Greg Wilson Curious Cat John Hunter curiouscat_com Herding Cats Glen Alleman Object Technology Jeff Sutherland jeffsutherland Tyner Blain Scott Sehlhorst sehlhorst StevenHarman.net Steven Harman stevenharman The Mendicant Bug Jason Adams ealdent Jbrains.ca J.B. Rainsberger jbrains Implementing Scrum Mike Vizdos mvizdos You'd think with all my video game experience... Jason Yip jchyip Petzold Book Blog Charles Petzold Lean Software Engineering Corey Ladas corey_ladas Quality through Innovation Adam Goucher adamgoucher Gray's Matter Justice Gray justicegray Lazycoder Scott Koon lazycoder The Agile Executive Israel Gat agile_exec Agile Advice (various) Test Obsessed Elisabeth Hendrickson testobsessed Agile Buddy Blog Jack Milunsky agilebuddy Enterprise Architecture: From Incite comes Insight... James McGovern mcgoverntheory Scott Bellware Scott Bellware bellware Eric.Weblog() Eric Sink Reforming Project Management Hal Macomber HalMacomber Agile Testing Grig Gheorghiu MrDave's (David Yack) Blog! David Yack davidyack Insights You Can Use Esther Derby estherderby Agile Developer Venkat's Blog Venkat Subramaniam venkat_s Codemonkeyism Stephan Schmidt codemonkeyism Software Project Management Pawel Brodzinski pawelbrodzinski DevelopSense Blog Michael Bolton michaelbolton Crazeegeekchick.com Dana Coffey crazeegeekchick Good coders code, great reuse Peteris Krumins pkrumins Coding the Architecture (various) Effective Software Development Dave Nicolette davenicolette Cory Foy Cory Foy cory_foy 10x Software Development Steve McConnell Ruminations of a Programmer Debasish Ghosh debasishg Cthulhu and Other Crazies Swizec swizec Moserware Jeff Moser jeffmoser Thought Clusters Krishna Kumar krishami Wille Faler's Buzzword Bingo Wille Faler wfaler AvailAgility Karl Scotland kjscotland Agile Software Process Improvement Jason Gorman jasongorman The Working Geek Andy Lester petdance Tester Tested! Pradeep Soundararajan testertested Clarke Ching - More Chilli Please Clarke Ching Information Technology Dark Side David Christiansen aldos LeadingAnswers Mike Griffiths Sceners.org sceners Focused Performance Frank Patrick fpatrick Software by Rob Rob Walling My Secret Life as a Spaghetti Coder Sammy Larbi codeodor Bit-Player Brian Hayes fede.carg ( blog ) Federico Cargnelutti fedecarg The Secrets of Consulting Gerald M. Weinberg jerryweinberg Notes from a Tool User Mark Levison mlevison Hot Needle of Inquiry Ron Jeffries ronjeffries Successful Software Andy Brice successfulsw Agile Chronicles (various) Word Aligned Thomas Guest thomasguest averyBlog James Avery averyj Antony Marcano's Blog Antony Marcano Legends of the Sun Pig Martin Sutherland sunpig NetObjectives (various) Thinking Tester Shrini Kulkarni shrinik The Braidy Tester Micahel Agility@Scale Scott W. Ambler scottwambler LitheSpeed's LitheBlog (various) Scrum 4 You Boris Gloger borisgloger Wide Awake Developers Michael Nygard mtnygard Silk and Spinach Kevin Rutherford kevinrutherford Me.Andering Willem van den Ende most_alive Agile in Action Simon Baker energizr 8th Light Blog (various) Edge of Chaos Michael Dubakov mdubakov Scaling Software Agility Dean Leffingwell Agile Development Thoughts Damon Poole damonpoole Jimmy Nilsson's Blog Jimmy Nilsson jimmynilsson Peripatetic Axiom Keith Braithwaite keithb_b Corporate Coder Eric Landes ericlandes The Build Doctor Julian Simpson builddoctor From the Editor of Methods & Tools Martinig I.M. Wright’s “Hard Code” Eric Brechner Collaborative Software Testing Jonathan Kohl Code Justin Justin David Chelimsky David Chelimsky dchelimsky @Kirkk.com Kirk Knoernschild pragkirk Enterprise Architecture & Other Enterprise Topics Mike Kavis madgreek65 Hicks-Wright.net Tyler Griffin Hicks-Wright Jonathan Babcock Jonathan Babcock jonbab1 PierG Piergiorgio Grossi pierg /var/log/mind Dhananjay Nene dnene Agile Game Development Clinton Keith Steve Rowe's Blog Steve Rowe steve_rowe Cauvin Roger L. Cauvin rcauvin Sander Hoogendoorn Sander Hoogendoorn aahoogendoorn Intergen Blog (various) teamintergen Shaping Software J.D. Meier Requirements Defined (various) seilevel Simple Architectures for Complex Enterprises Roger Sessions rsessions Chris McMahon's Blog Chris McMahon chris_mcmahon Agile Artisans Jared Richardson jaredrichardson Agile Web Operations (various) mmarschall Jcooney.NET Joseph Cooney josephcooney Partnership & Possibilities Diana Larsen dianaofportland Agile Anarchy Tobias Mayer tobiasgmayer Paircoaching's Weblog Yves Hanoulle yveshanoulle James Grenning’s Blog James Grenning jwgrenning George Dinwiddie's Blog George Dinwiddie gdinwiddie On Software Development, Agile, Startups, and Social Networking Isaac Sacolick nyike Rob Bowley Rob Bowley robbowley Caffeinated Coder Russell Ball caffeinatedtwit Mult.ifario.us Paul R. Brown paulrbrown It's Common Sense, Stupid Soon Hui Ngu Matt O’ Rama Matt Grommes mattgrommes Under the Wire (various) Project Management 2.0 Andrew Filev andrewsthoughts Bartosz Milewski's Programming Cafe Bartosz Milewski BartoszMilewski Steve Freeman Steve Freeman Agile CMMI Blog Hillel Glazer hi11e1 Agile Elephant Jordan Haberfield jordanhaber Musings of a Software Development Manager Ed Gibbs edward_gibbs Engineering Game Development Lee Winder spreetree Technology Architecture & Projects Robert McIlree rmcilree The Hacker Chick Blog Abby Fichtner HackerChick A Test Guy Dave Liebreich atestguy Kallokain Henrik Mårtensson Kallokain Rebecca's Blog Rebecca Wirfs-Brock Ytechie Jason Young ytechie DrunkenPM Dave Prior mrsungo Legend TT = This Time LT = Last Time  Note: for some of the statistics I happily used the script that was kindly supplied by Steven Machtelinckx. This saved me a lot of time... Thanks Steven! 原始地址:http://www.noop.nl/2009/09/top-200-blogs-for-developers-q3-2009.html 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2010/03/11/bloger.html,如需转载请自行联系原作者

掌握 Dojo 工具包,第 1 部分: Dojo 入门简介 掌握 Dojo 工具包,第 2 部分: XHR 框架与 Dojo 掌握 Dojo 工具包,第 3 部分: Dojo 事件机制 掌握 Dojo 工具包,第 4 部分: Dojo 中的拖拽 掌握 Dojo 工具包,第 5 部分: Dojo 的 UI 组件库 - Dijit 掌握 Dojo 工具包,第 6 部分: Dojo Widget 的高级应用 掌握 Dojo 工具包,第 7 部分: Dojo 的扩展 掌握 Dojo 工具包,第 8 部分: 明日之星 - DojoX 掌握 Dojo 工具包,第 9 部分: Dojo 国际化 原文地址:http://www.cnblogs.com/rubylouvre/archive/2010/06/06/1752472.html 本文转自Justin博客园博客,原文链接:http://www.cnblogs.com/justinw/archive/2010/06/07/1753467.html,如需转载请自行联系原作者

python报错问题解决:'ascii' codec can't encode character

之前部署了openstack虚拟化环境,有一天在使用nova list查看虚拟机的时候,突然报错!如下: [root@linux-node1 src]# nova listERROR (UnicodeEncodeError): 'ascii' codec can't encode character u'\uff08' in position 9: ordinal not in range(128) python在安装时,默认的编码是ascii,当程序中出现非ascii编码时,python的处理常常会报这样的错,python没办法处理非ascii编码的,此时需要自己设置将python的默认编码,一般设置为utf8的编码格式。 查阅网上,可以在程序中修改所有涉及到编码的地方,强制编码为utf8,即添加代码encode("utf8"),这种方法并不推荐使用,因为一旦少写一个地方,将会导致大量的错误报告。 -------------------------------------------------这里介绍一个一次性修改后永久生效的方法: 在python的lib\site-packages文件夹下新建一个sitecustomize.py [root@linux-node1 nova]# find / -name site-packages/usr/lib/python2.7/site-packages /usr/lib64/python2.7/site-packages [root@linux-node1 nova]# cd /usr/lib/python2.7/site-packages/ [root@linux-node1 site-packages]# cat sitecustomize.py #添加如下内容,设置编码为utf8# encoding=utf8 import sys reload(sys) sys.setdefaultencoding('utf8') 此时重启python解释器,执行sys.getdefaultencoding(),发现编码已经被设置为utf8的了,多次重启之后,效果相同,这是因为系统在python启动的时候,自行调用该文件,设置系统的默认编码,而不需要每次都手动的加上解决代码,属于一劳永逸的解决方法。 [root@linux-node1 nova]# python                                       #终端进入python,即是重启python解释器!可以多次进入 Python 2.7.5 (default, Aug 18 2016, 15:58:25)  [GCC 4.8.5 20150623 (Red Hat 4.8.5-4)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> 接着,再次使用nova list命令,就没有那个报错了! [root@linux-node1 src]# nova list +--------------------------------------+----------------------------+--------+------------+-------------+--------------------+ | ID | Name | Status | Task State | Power State | Networks | +--------------------------------------+----------------------------+--------+------------+-------------+--------------------+ | b6a4738d-7e01-4068-a09b-7008b612d126 | beta-new1(beta环境1) | ACTIVE | - | Running | flat=192.168.1.151 | | 9acdb28b-02c2-41bb-87c4-5f3a8fa008ab | dev-new-test1(测试环境1) | ACTIVE | - | Running | flat=192.168.1.150 | | 30e5ba3e-3942-4119-9ba6-7523cf865b6f | kvm-server003 | ACTIVE | - | Running | flat=192.168.1.152 | | a2893208-3ec9-4606-ab82-d7a870206cb9 | kvm-server004 | ACTIVE | - | Running | flat=192.168.1.153 | | 3483d9f1-4015-48d9-9837-b67ca82dd54d | kvm-server005 | ACTIVE | - | Running | flat=192.168.1.154 | +--------------------------------------+----------------------------+--------+------------+-------------+--------------------+ ***************当你发现自己的才华撑不起野心时,就请安静下来学习吧*************** 分类: 虚拟化,Python 本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/5893121.html,如需转载请自行联系原作者

关于AJAX跨域调用ASP.NET MVC或者WebAPI服务的问题及解决方案

当跨域(cross domain)调用ASP.NET MVC或者ASP.NET Web API编写的服务时,会发生无法访问的情况。 使用模板创建一个最简单的ASP.NET Web API项目,调试起来确认能正常工作 创建另外一个项目,仅仅包含一个HTML页面,发起AJAX的调用 在浏览器中打开这个网页,我们会发现如下的错误(405:Method Not Allowed) 【备注】同样的情况,也发生在ASP.NET MVC中。某些时候,MVC也可以直接用来开发服务,与WebAPI相比各有优缺点。下面是一个利用MVC开发的服务的例子 跨域问题仅仅发生在Javascript发起AJAX调用,或者Silverlight发起服务调用时,其根本原因是因为浏览器对于这两种请求,所给予的权限是较低的,通常只允许调用本域中的资源,除非目标服务器明确地告知它允许跨域调用。 所以,跨域的问题虽然是由于浏览器的行为产生出来的,但解决的方法却是在服务端。因为不可能要求所有客户端降低安全性。 针对ASP.NET MVC和ASP.NET Web API两种项目类型,我做了一些研究,确定下面的方案是可行的。 针对ASP.NET MVC,只需要在web.config中添加如下的内容即可 <system.webServer> <httpProtocol> <customHeaders> <add name="Access-Control-Allow-Origin" value="*" /> <add name="Access-Control-Allow-Headers" value="Content-Type" /> <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" /> </customHeaders> </httpProtocol> <handlers> <remove name="ExtensionlessUrlHandler-Integrated-4.0" /> <remove name="OPTIONSVerbHandler" /> <remove name="TRACEVerbHandler" /> <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" /> </handlers> </system.webServer> 针对ASP.NET Web API,除了上面这样的设置,还需要添加一个特殊的设计,就是为每个APIController添加一个OPTIONS的方法,但无需返回任何东西。 public string Options() return null; // HTTP 200 response with empty body 【备注】这个功能也可以进行一些研究,设计成Filter的形式可能就更好了。 分类: ASP.NET 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/4846791.html,如需转载请自行联系原作者

sql server2000中使用convert来取得datetime数据类型样式(全) 日期数据格式的处理,两个示例: CONVERT(varchar(16), 时间一, 20) 结果:2007-02-01 08:02/*时间一般为getdate()函数或数据表里的字段*/ CONVERT(varchar(10), 时间一, 23) 结果:2007-02-01 /*varchar(10)表示日期输出的格式,如果不够长会发生截取*/ 语句及查询结果: Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE(), 1): 05/16/06 Select CONVERT(varchar(100), GETDATE(), 2): 06.05.16 Select CONVERT(varchar(100), GETDATE(), 3): 16/05/06 Select CONVERT(varchar(100), GETDATE(), 4): 16.05.06 Select CONVERT(varchar(100), GETDATE(), 5): 16-05-06 Select CONVERT(varchar(100), GETDATE(), 6): 16 05 06 Select CONVERT(varchar(100), GETDATE(), 7): 05 16, 06 Select CONVERT(varchar(100), GETDATE(), 8): 10:57:46 Select CONVERT(varchar(100), GETDATE(), 9): 05 16 2006 10:57:46:827AM Select CONVERT(varchar(100), GETDATE(), 10): 05-16-06 Select CONVERT(varchar(100), GETDATE(), 11): 06/05/16 Select CONVERT(varchar(100), GETDATE(), 12): 060516 Select CONVERT(varchar(100), GETDATE(), 13): 16 05 2006 10:57:46:937 Select CONVERT(varchar(100), GETDATE(), 14): 10:57:46:967 Select CONVERT(varchar(100), GETDATE(), 20): 2006-05-16 10:57:47 Select CONVERT(varchar(100), GETDATE(), 21): 2006-05-16 10:57:47.157 Select CONVERT(varchar(100), GETDATE(), 22): 05/16/06 10:57:47 AM Select CONVERT(varchar(100), GETDATE(), 23): 2006-05-16 Select CONVERT(varchar(100), GETDATE(), 24): 10:57:47 Select CONVERT(varchar(100), GETDATE(), 25): 2006-05-16 10:57:47.250 Select CONVERT(varchar(100), GETDATE(), 100): 05 16 2006 10:57AM Select CONVERT(varchar(100), GETDATE(), 101): 05/16/2006 Select CONVERT(varchar(100), GETDATE(), 102): 2006.05.16 Select CONVERT(varchar(100), GETDATE(), 103): 16/05/2006 Select CONVERT(varchar(100), GETDATE(), 104): 16.05.2006 Select CONVERT(varchar(100), GETDATE(), 105): 16-05-2006 Select CONVERT(varchar(100), GETDATE(), 106): 16 05 2006 Select CONVERT(varchar(100), GETDATE(), 107): 05 16, 2006 Select CONVERT(varchar(100), GETDATE(), 108): 10:57:49 Select CONVERT(varchar(100), GETDATE(), 109): 05 16 2006 10:57:49:437AM Select CONVERT(varchar(100), GETDATE(), 110): 05-16-2006 Select CONVERT(varchar(100), GETDATE(), 111): 2006/05/16 Select CONVERT(varchar(100), GETDATE(), 112): 20060516 Select CONVERT(varchar(100), GETDATE(), 113): 16 05 2006 10:57:49:513 Select CONVERT(varchar(100), GETDATE(), 114): 10:57:49:547 Select CONVERT(varchar(100), GETDATE(), 120): 2006-05-16 10:57:49 Select CONVERT(varchar(100), GETDATE(), 121): 2006-05-16 10:57:49.700 Select CONVERT(varchar(100), GETDATE(), 126): 2006-05-16T10:57:49.827 Select CONVERT(varchar(100), GETDATE(), 130): 18 ???? ?????? 1427 10:57:49:907AM Select CONVERT(varchar(100), GETDATE(), 131): 18/04/1427 10:57:49:920AM 使用 CONVERT: CONVERT ( data_type [ ( length ) ] , expression [ , style ] ) expression 是任何有效的 Microsoft® SQL Server™ 表达式。。  data_type 目标系统所提供的数据类型,包括 bigint 和 sql_variant。不能使用用户定义的数据类型。 length nchar、nvarchar、char、varchar、binary 或 varbinary 数据类型的可选参数。  style 日期格式样式,借以将 datetime 或 smalldatetime 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型);或者字符串格式样式,借以将 float、real、money 或 smallmoney 数据转换为字符数据(nchar、nvarchar、char、varchar、nchar 或 nvarchar 数据类型)。 SQL Server 支持使用科威特算法的阿拉伯样式中的数据格式。 在表中,左侧的两列表示将 datetime 或 smalldatetime 转换为字符数据的 style 值。给 style 值加 100,可获得包括世纪数位的四位年份 (yyyy)。 不带世纪数位 (yy) 带世纪数位 (yyyy)  输入/输出**  - 0 或 100 (*) 默认值 mon dd yyyy hh:miAM(或 PM)  1 101 美国 mm/dd/yyyy  2 102 ANSI yy.mm.dd  3 103 英国/法国 dd/mm/yy  4 104 德国 dd.mm.yy  5 105 意大利 dd-mm-yy  6 106 - dd mon yy  7 107 - mon dd, yy  8 108 - hh:mm:ss  - 9 或 109 (*) 默认值 + 毫秒 mon dd yyyy hh:mi:ss:mmmAM(或 PM)  10 110 美国 mm-dd-yy  11 111 日本 yy/mm/dd  12 112 ISO yymmdd  - 13 或 113 (*) 欧洲默认值 + 毫秒 dd mon yyyy hh:mm:ss:mmm(24h)  14 114 - hh:mi:ss:mmm(24h)  - 20 或 120 (*) ODBC 规范 yyyy-mm-dd hh:mm:ss[.fff]  - 21 或 121 (*) ODBC 规范(带毫秒) yyyy-mm-dd hh:mm:ss[.fff]  - 126(***) ISO8601 yyyy-mm-dd Thh:mm:ss.mmm(不含空格)  - 130* Hijri**** dd mon yyyy hh:mi:ss:mmmAM  - 131* Hijri**** dd/mm/yy hh:mi:ss:mmmAM  * 默认值(style 0 或 100、9 或 109、13 或 113、20 或 120、21 或 121)始终返回世纪数位 (yyyy)。 ** 当转换为 datetime时输入;当转换为字符数据时输出。 *** 专门用于 XML。对于从 datetime或 smalldatetime 到 character 数据的转换,输出格式如表中所示。对于从 float、money 或 smallmoney 到 character 数据的转换,输出等同于 style 2。对于从 real 到 character 数据的转换,输出等同于 style 1。 ****Hijri 是具有几种变化形式的日历系统,Microsoft® SQL Server™ 2000 使用其中的科威特算法。 重要 默认情况下,SQL Server 根据截止年份 2049 解释两位数字的年份。即,两位数字的年份 49 被解释为 2049,而两位数字的年份 50 被解释为 1950。许多客户端应用程序(例如那些基于 OLE 自动化对象的客户端应用程序)都使用 2030 作为截止年份。SQL Server 提供一个配置选项("两位数字的截止年份"),借以更改 SQL Server 所使用的截止年份并对日期进行一致性处理。然而最安全的办法是指定四位数字年份。 当从 smalldatetime 转换为字符数据时,包含秒或毫秒的样式将在这些位置上显示零。当从 datetime 或 smalldatetime 值进行转换时,可以通过使用适当的 char 或 varchar 数据类型长度来截断不需要的日期部分。 分类: SQL 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/4939304.html,如需转载请自行联系原作者

redis持久化策略梳理及主从环境下的策略调整记录

redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来保证持久化。可以不定期的通过异步方式保存到磁盘上(即“半持久化模式”);也可以把每一次数据变化都写入到一个Append Only File(AOF)里面(即“完全持久化模式”)。redis支持两种持久化方式,一种是默认方式的RDB(Snapshotting快照)持久化,另一种是AOF(Append-only file)持久化方式。这两种持久化方式都可以将内存中的数据库状态保存到磁盘上,redis对应的也有两种落地文件:数据文件(默认文件名dump.rdb,也即快照文件)、AOF持久化文件。接下来详细说明它们之间的用法: 1.RDB是在指定时间间隔内生成数据集的时间点快照(point-in-time snapshot)持久化,它是记录一段时间内的操作,一段时间内操作超过多少次就持久化。 默认是会以快照的形式将数据持久化到磁盘的(一个二进制文件,dump.rdb,这个文件名字可以指定),在配置文件中的格式是:save N M表示在N秒之内,redis至少发生M次修改则redis抓快照到磁盘。当然也可以手动执行save或者bgsave(异步)做快照。工作原理: 当redis需要做持久化时,redis会fork一个子进程;子进程将数据写到磁盘上一个临时RDB文件中;当子进程完成写临时文件后,将原来的RDB替换掉,这样的好处就是可以copy-on-write(写时复制技术) 2.AOF持久化记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集,它可以实现每次操作都持久化。 AOF文件中的命令全部以redis协议的格式来保存,新命令会被追加到文件的末尾。 redis还可以在后台对AOF文件进行重写(rewrite),使得AOF文件的体积不会超出保存数据集状态所需的实际大小。redis还可以同时使用AOF持久化和RDB持久化。在这种情况下,当redis重启时,它会优先使用AOF文件来还原数据集, 因为AOF文件保存的数据集通常比RDB文件所保存的数据集更完整。也可以关闭持久化功能,让数据只在服务器运行时存在。 RDB方法在redis异常死掉时,最近的数据会丢失(丢失数据的多少视你save策略的配置),所以这是它最大的缺点,当业务量很大时,丢失的数据是很多的。Append-only方法可以做到全部数据不丢失,但redis的性能就要差些。AOF就可以做到全程持久化,只需要在配置文件中开启(默认是no),appendonly yes开启AOF之后,redis每执行一个修改数据的命令,都会把它添加到aof文件中,当redis重启时,将会读取AOF文件进行“重放”以恢复到redis关闭前的最后时刻。 redis启动装载:AOF优先于RDB RDB性能优于AOF,因为里面没有重复 Redis一次性将数据加载到内存中,一次性预热 LOG Rewriting(重写)随着修改数据的执行AOF文件会越来越大,其中很多内容记录某一个key的变化情况。因此redis有了一种比较有意思的特性:在后台重建AOF文件,而不会影响client端操作。在任何时候执行bgrewriteaof命令,都会把当前内存中最短序列的命令写到磁盘,这些命令可以完全构建当前的数据情况,而不会存在多余的变化情况(比如状态变化,计数器变化等),缩小的AOF文件的大小。所以当使用AOF时,redis推荐同时使用bgrewriteaof。AOF 重写和 RDB 创建快照一样,都巧妙地利用了写时复制机制。 为了压缩AOF的持久化文件,Redis提供了bgrewriteaof命令。 收到此命令后Redis将使用与快照类似的方式将内存中的数据以命令的方式保存到临时文件中,最后替换原来的文件,以此来实现控制AOF文件的增长。 由于是模拟快照的过程,因此在重写AOF文件时并没有读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件。 AOF文件刷新的方式,有三种,参考配置参数appendfsync :     appendfsync always:每提交一个修改命令都调用fsync刷新到AOF文件,非常非常慢,但也非常安全;     appendfsync everysec:每秒钟都调用fsync刷新到AOF文件,很快,但可能会丢失一秒以内的数据;     appendfsync no:依靠OS进行刷新,redis不主动刷新AOF,这样最快,但安全性就差。默认并推荐每秒刷新,这样在速度和安全上都做到了兼顾。 redis默认的持久化方式是RDB,数据写入到dump文件中。如果要启用AOF持久化,就在redis.conf文件中配置如下:     appendonly yes       #启用AOF持久化方式     appendfilename "appendonly.aof"      #AOF文件的名称,默认为appendonly.aof     # appendfsync always       #每次收到写命令就立即强制写入磁盘,是最有保证的完全的持久化,但速度也是最慢的,一般不推荐使用。    appendfsync everysec       #每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,这种fsync策略可以兼顾速度和安全性,是受推荐的方式。    # appendfsync no       #完全依赖OS的写入,一般为30秒左右一次,性能最好但是持久化最没有保证,不被推荐。 可能由于系统原因导致了AOF损坏,redis无法再加载这个出错的AOF文件,可以按照下面步骤来修复:     1)首先做一个AOF文件的备份,复制到其他地方;     2)修复原始AOF文件,执行命令redis-check-aof –fix ;     3)可以通过diff –u命令来查看修复前后文件不一致的地方;     4)重启redis服务。 LOG Rewrite的工作原理: 同样用到了copy-on-write:首先redis会fork一个子进程;子进程将最新的AOF写入一个临时文件;父进程增量的把内存中的最新执行的修改写入(这时仍写入旧的AOF,rewrite如果失败也是安全的);当子进程完成rewrite临时文件后,父进程会收到一个信号,并把之前内存中增量的修改写入临时文件末尾;这时redis将旧AOF文件重命名,临时文件重命名,开始向新的AOF中写入。 为以防万一(机器坏掉或磁盘坏掉),最好定期把使用filesnapshotting 或 Append-only 生成的*rdb *.aof文件备份到远程机器上,然后可以用crontab定时(比如每半小时)scp一次。如果没有使用redis的主从功能 ,半小时备份一次应该是可以了;并且如果应用数据量不大的话,可以单机部署,做主从有点浪费。具体还是要根据应用而定。 接着具体解说下这两种持久化: 如果的内存中的数据量非常大的时候,rdb持久化的临时文件就会非常大,几乎是原文件的1倍,性能有所降低。 如果当写操作要立刻持久化的时候,可以执行命令:save save是全阻塞的,bgsave是异步的。 snapshot快照首先将数据写入临时文件,当成功结束后,将临时文件重名为dump.rdb 使用RDB恢复数据: 自动的持久化数据存储到dump.rdb后。实际只要重启redis服务即可完成(启动redis的server时会从dump.rdb中先同步数据) 客户端使用命令进行持久化save存储: # redis-cli -h ip -p port save # redis-cli -h ip -p port bgsave 一个是在前台进行存储,一个是在后台进行存储。我的client就在server这台服务器上,所以不需要连其他机器,直接./redis-cli bgsave。 由于redis是用一个主线程来处理所有 client的请求,这种方式会阻塞所有client请求。所以不推荐使用。另一点需要注意的是,每次快照持久 化都是将内存数据完整写入到磁盘一次,并不是增量的只同步脏数据。如果数据量大的话,而且写操作比较多,必然会引起大量的磁盘io操作,可能会严重影响性能 如果aof或rdb文件语法有误,可以使用下面两条命令来修复。 1)aof修复命令: # redis-check-aof --fix appendonlly.aof 2)rdb修复命令: # redis-check-rdb--fix dump.rdb aof是采用文件追加方式,将所有的写操作保存在aof文件中,当文件越来越大时,有可能存在相同的写操作,这些相同的操作可以将他浓缩为一条操作,这样可以减少aof文件的容量。 redis对aof新增了一种重写机制,当aof文件大小超过所设定的阈值时,redis会启动aof文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof。 RDB和AOF各自的优缺点1)RDB持久化优点 RDB 是一个非常紧凑(compact)的文件,它保存了Redis在某个时间点上的数据集。 这种文件非常适合用于进行备份的,比如说,可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个 RDB 文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB 非常适用于灾难恢复(disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊 S3 中。RDB可以最大化 Redis 的性能:父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。RDB在恢复大数据集时的速度比AOF的恢复速度要快。     RDB持久化缺点 如果需要尽量避免在服务器故障时丢失数据,那么RDB不适合这种情况。 虽然Redis允许设置不同的保存点(save point)来控制保存RDB文件的频率,但是因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此你可能会至少5分钟才保存一次RDB文件。在这种情况下, 一旦发生故障停机,就可能会丢失好几分钟的数据。每次保存RDB的时候,Redis都要 fork() 出一个子进程,并由子进程来进行实际的持久化工作。在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 虽然 AOF 重写也需要进行 fork() ,但无论 AOF 重写的执行间隔有多长,数据的耐久性都不会有任何损失。 2)AOF持久化优点 使用AOF持久化会让Redis变得非常耐久(much more durable):你可以设置不同的fsync 策略,比如无fsync ,每秒钟一次 fsync ,或者每次执行写入命令时fsync 。AOF的默认策略为每秒钟fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)。AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。 Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写:重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新AOF文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以Redis协议的格式保存, 因此AOF文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器,移除AOF文件末尾的FLUSHALL命令, 并重启Redis ,就可以将数据集恢复到 FLUSHALL 执行之前的状态。    AOF持久化缺点 对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积。根据所使用的fsync策略,AOF的速度可能会慢于RDB 。在一般情况下,每秒 fsync 的性能依然非常高,而关闭fsync可以让AOF的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。AOF 在过去曾经发生过这样的 bug : 因为个别命令的原因,导致 AOF 文件在重新载入时,无法将数据集恢复成保存时的原样。 (举个例子,阻塞命令BRPOPLPUSH就曾经引起过这样的 bug 。)测试套件里为这种情况添加了测试:它们会自动生成随机的、复杂的数据集,并通过重新载入这些数据来确保一切正常。 虽然这种 bug 在 AOF 文件中并不常见, 但是对比来说, RDB 几乎是不可能出现这种 bug 的。 RDB持久化和AOF持久化,应该用哪一个? 一般来说,如果想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能。 如果非常关心数据,但仍然可以承受数分钟以内的数据丢失, 那么可以只使用RDB持久化。 不推荐只使用AOF持久化:因为定时生成RDB快照(snapshot)非常便于进行数据库备份,并且RDB恢复数据集的速度也要比 AOF 恢复的速度要快,除此之外,使用RDB还可以避免之前提到的AOF程序的bug。 在默认情况下,Redis将数据库快照保存在名字为dump.rdb的二进制文件中。可以对Redis 进行设置, 让它在“ N 秒内数据集至少有M个改动”这一条件被满足时,自动保存一次数据集。也可以通过调用 SAVE 或者 BGSAVE , 手动让 Redis 进行数据集保存操作。比如说, 以下设置会让 Redis 在满足“ 60 秒内有至少有1000个键被改动”这一条件时,自动保存一次数据集: save 60 1000 这种持久化方式被称为快照(snapshot)。 快照的运作方式: 当 Redis 需要保存 dump.rdb 文件时, 服务器执行以下操作: Redis 调用 fork() ,同时拥有父进程和子进程。 子进程将数据集写入到一个临时 RDB 文件中。 当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。 这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。 只进行追加操作的文件(append-only file,AOF) 快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。尽管对于某些程序来说, 数据的耐久性并不是最重要的考虑因素, 但是对于那些追求完全耐久能力(full durability)的程序来说, 快照功能就不太适用了。 从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。 你可以通过修改配置文件来打开 AOF 功能: appendonly yes 从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。 这样的话, 当 Redis 重新启时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。 下面是redis默认的快照设置(要想关闭save快照功能,即注释掉这三个默认的save设置即可): save 900 1      #当有一条Keys数据被改变时,900秒刷新到Disk一次 save 300 10    #当有10条Keys数据被改变时,300秒刷新到Disk一次 save 60 10000    #当有10000条Keys数据被改变时,60秒刷新到Disk一次Redis的RDB文件不会坏掉,因为其写操作是在一个新进程中进行的。 当生成一个新的RDB文件时,Redis生成的子进程会先将数据写到一个临时文件中,然后通过原子性rename系统调用将临时文件重命名为RDB文件。这样在任何时候出现故障,Redis的RDB文件都总是可用的。 同时,Redis的RDB文件也是Redis主从同步内部实现中的一环。 第一次Slave向Master同步的实现是: Slave向Master发出同步请求,Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的命令转发给Slave,初次同步完成。 第二次以及以后的同步实现是: Master将变量的快照直接实时依次发送给各个Slave。 但不管什么原因导致Slave和Master断开重连都会重复以上两个步骤的过程。 Redis的主从复制是建立在内存快照的持久化基础上的,只要有Slave就一定会有内存快照发生。 可以很明显的看到,RDB有它的不足,就是一旦数据库出现问题,那么我们的RDB文件中保存的数据并不是全新的。 从上次RDB文件生成到Redis停机这段时间的数据全部丢掉了。 AOF重写: 因为 AOF 的运作方式是不断地将命令追加到文件的末尾, 所以随着写入命令的不断增加, AOF 文件的体积也会变得越来越大。举个例子, 如果你对一个计数器调用了 100 次 INCR , 那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录(entry)。然而在实际上, 只使用一条 SET 命令已经足以保存计数器的当前值了, 其余 99 条记录实际上都是多余的。为了处理这种情况, Redis 支持一种有趣的特性: 可以在不打断服务客户端的情况下, 对AOF文件进行重建(rebuild)。执行 BGREWRITEAOF 命令, Redis将生成一个新的AOF文件,这个文件包含重建当前数据集所需的最少命令。 RDB和AOF之间的相互作用: 在版本号大于等于 2.4 的 Redis 中, BGSAVE 执行的过程中, 不可以执行 BGREWRITEAOF 。 反过来说, 在 BGREWRITEAOF 执行的过程中, 也不可以执行 BGSAVE 。 这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。 如果 BGSAVE 正在执行, 并且用户显示地调用 BGREWRITEAOF 命令, 那么服务器将向用户回复一个 OK 状态, 并告知用户, BGREWRITEAOF 已经被预定执行: 一旦 BGSAVE 执行完毕, BGREWRITEAOF 就会正式开始。当 Redis 启动时, 如果 RDB 持久化和 AOF 持久化都被打开了, 那么程序会优先使用 AOF 文件来恢复数据集, 因为 AOF 文件所保存的数据通常是最完整的。 备份Redis 数据: Redis对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的 RDB 文件时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用 原子地用临时文件替换原来的 RDB 文件。这也就是说, 无论何时, 复制 RDB 文件都是绝对安全的。 ----------------------------------------------------------------------------------------------------------------------------------------------公司线上redis主从环境下的持久化策略调整: 之前线上项目使用redis,部署了redis主从环境。redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此下去,形成了强大的多级服务器集群架构。由于主redis采用了AOF和save快照的持久化,长时间下去,aof文件不断增大,磁盘空间使用率逐渐暴增。 考虑到性能问题,需要对redis持久化做些调整,调整如下:    1)主库不开启AOF持久化,并关闭save快照功能(即注释默认的三个save设置),只在每晚12点定时手动做一次bgsave快照,并将快照文件转移到异地。即主库上不产生appendonly.aof持久化文件,做的快照数据放在.rdb文件里(如dump.rdb,由于是压缩配置(rdbcompression yes表示快照文件要压缩),所以快照文件要比aof文件小),然后将这个快照文件dump.rdb转移到其他的服务器上,防止主服务器宕机造成的损失!    2)从库开启AOF持久化并1秒落地,同样不做快照save。并在每晚12点做一次bgrewriteaof压缩appendonly.aof持久化文件,压缩前先对aof文件进行备份。-------------------------------------------------------------------------------------------------------------------------------------------- 按照这种方法进行redis持久化调整,由于线上redis的主库之前采用了AOF和save快照的持久化,之后将这两种都关闭,从库采用AOF持久化。出现了下面的现象: 就是主库关闭AOF和save快照后,主redis上的appendonly.aof持久化文件在一段时间内还在刷,在增大,这是正常的,由于之前开启的缘故,刷过一段时间,主redis的appendonly.aof持久化文件就不刷了,只有从redis的appendonly.aof持久化文件在刷了-------------------------------------------------------------------------------------------------------------------------------------------- 主从redis部署的主要目的:数据持久化,灾难恢复,冗余。主库不落地,减少消耗。 1)主库不做AOF,不做快照,允许从库访问即可。 2)从库开启AOF,不做save 3)备份策略: 主库每晚12点整给每个实例手动做一次bgsave快照,并将快照文件备份到远程节点上。 从库每晚12点整对AOF文件打包备份(tar),打包备份后做一次AOF文件压缩(bgrewriteaof)。每天的数据起始点是前一天晚上rewriteaof后的数据。 主库服务器脚本: 即主库快照之后,将快照文件转移到异地即从库机器192.168.1.121/135上面。 rsync -av /data/redis/dump.rdb root@192.168.1.121:/data/backup/192.168.1.132-save/$CURHOUR/ rsync -av /data/redis/dump.rdb root@192.168.1.135:/data/backup/192.168.1.132-save/$CURHOUR/ sleep 10 date >> /data/logs/bgsave.log #/bin/rm -rf `date -d -30day + "%Y%m%d"` find /data/backup/redis/ -mtime +30 | xargs rm -rf echo "Backup $REDISNAME ok at $CURTIME !" >> $LOGFILE [root@cdn redis]# crontab -e 59 23 * * * /bin/bash /data/redis/redis_backup.sh >/dev/null 2>&1 [root@cdn redis]# cd /data/backup/redis/20161207_13 [root@cdn 20161207_13]# ls  appendonly.7000_20161207_133131.tar.gz -------------再看一例---------------------------------------------------------------------------------------------------------------------- 公司线上一个项目数据存储采用MySQL,共分为10个库,分布在4台机器上,每个库数据量约为10G,各机器均采用RAID5加速磁盘访问; 当同时在线人数达高峰期(10w),DB磁盘IO压力巨大,导致访问巨慢,,在线人数就很难上不去了。 针对上面描述情况,使用redis后可有效解决这一瓶颈,因为Redis数据读写都是直接操作内。 解决方案: 将部分数据压缩导入到redis后,总数据量约30G(转换成redis数据类型数据量),一主一从模型,共两组。 一台机器内存32G,开10个实例,共20个实例,多实例方便做持久化。 同样适用于上面的redis持久化策略调整方案(思路和上面一致) 主从库配置:主库:关闭save开展,aof默认不打开,允许从库访问。主库设置了密码访问requirepass My#redis从库:需增加配置:开启AOF持久化,关闭save快照,设置密码; 从库10个实例的配置文件分别为:slave6001.conf ~ slave6010.conf slave6001.conf配置内容如下(其他实例拷贝这个,修改端口等其他信息即可) /data/sh/redis_backup.sh slave${PORT} && echo “slave${PORT} ok `date +%Y%m%d_%H%M%S`” >> $LOGFILE 2>&1 || echo “slave${PORT} backup error” >> $LOGFILE 2>&1 操作注意事项 1)若主库挂了,不能直接开启主库程序。若直接开启主库程序将会冲掉从库的AOF文件,这样将导致只能恢复到前一天晚上12的备份。 2)程序在跑时,不能重启网络(程序是通过网络接口的端口进行读写的)。网络中断将导致中断期间数据丢失。 3)确定配置文件全部正确才启动(尤其不能有数据文件名相同),否则会冲掉原来的文件,可能造成无法恢复的损失。 灾难恢复1)主库故障,快速恢复到最近状态描述:主库挂了(redis程序挂了/机器宕机了),从库正常,恢复到主库挂掉的时间点:去从库手动做一次快照,拷贝快照到主库相应目录,启动,OK。 在从库做一次快照,转移快照文件到其他目录,将快照文件目录拷贝到主库相应目录,启动主库,OK! ( /data/sh/redis_bgsave_cp.sh ) 启动从库。 做快照,拷贝到主库,启动主库(同上面第1)步)。 3)恢复到两天或几天前12点状态从库每晚备份要备份AOF未bgrewriteaof之前的数据,可根据当天晚上12点备份,没有bfrewriteaof之前的AOF文件来进行恢复,方法同上面的第2)步。 ***************当你发现自己的才华撑不起野心时,就请安静下来学习吧*************** 本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/6266319.html,如需转载请自行联系原作者

(2)什么时候使用装饰设计模式                当我们需要对一个类进行增强的时候,增强后的类不再当前类的范畴                     例如:现在有一个     Animal类     Cat和Dog都属于动物类型,因此可以直接继承                                                                       现在新来一个“电子狗 ”,不属于动物的范围,但是有需要用其中的方法,这时候我们选择使用装饰(包装)设计模式 一:需求:统一解决请求参数中文乱码 二:需求原因:      在没有该需求之前,解决请求乱码问题:           (1)POST: 1 //第一种 2 //request.setCharacterEncoding(this.getServletContext().getInitParameter("charset")); 3 //备注:这种获取方式是因为在web.xml中进行了如下配置 4 <!-- 设置编码 --> 5 <context-param> 6 <param-name>charset</param-name> 7 <param-value>UTF-8</param-value> 8 </context-param> 10 //第二种 11 request.setCharacterEncoding("utf-8"); 1 String value = request.getParameter("value"); 2 if(value == null || value.trim().equals("")){ 3 value=""; 4 } 5 value = new String(value.getBytes("ISO-8859-1"),"utf-8"); 三、优化思路:      使用一个过滤器,在请求到达servlet之前,先对request对象设置编码      要求所有的请求都要进行设置编码,因此所有的request都要拦截,进行增强,那么: 1 <filter> 2 <filter-name>EncodingFilter</filter-name> 3 <filter-class>com.cqy.filter.EncodingFilter</filter-class> 4 </filter> 6 <filter-mapping> 7 <filter-name>EncodingFilter</filter-name> 8 <url-pattern>/*</url-pattern> 9 </filter-mapping> 5 import javax.servlet.Filter; 6 import javax.servlet.FilterChain; 7 import javax.servlet.FilterConfig; 8 import javax.servlet.ServletException; 9 import javax.servlet.ServletRequest; 10 import javax.servlet.ServletResponse; 11 import javax.servlet.http.HttpServletRequest; 12 import javax.servlet.http.HttpServletResponse; 14 import com.cqy.domain.MyRequest; 16 public class EncodingFilter implements Filter { 18 @Override 19 public void destroy() { 21 } 23 @Override 24 public void doFilter(ServletRequest req, ServletResponse res, 25 FilterChain chain) throws IOException, ServletException { 26 // 将请求和响应强制转换成Http形式 27 HttpServletRequest request = (HttpServletRequest) req; 28 HttpServletResponse response = (HttpServletResponse) res; 30 // 处理响应乱码 31 response.setContentType("text/html;charset=utf-8"); 33 // 自定义一个request对象:MyRequest,对服务器原来的requset进行增强,使用装饰设计模式 34 // 要增强原来的request对象,必须先获取到原来的request对象 35 MyRequest myRequest = new MyRequest(request); 37 // 注意:放行的时候应该传入增强后的request对象 38 chain.doFilter(myRequest, response); 39 } 41 @Override 42 public void init(FilterConfig arg0) throws ServletException { 44 } 3 import java.io.UnsupportedEncodingException; 4 import java.util.Map; 5 import java.util.Set; 7 import javax.servlet.http.HttpServletRequest; 8 import javax.servlet.http.HttpServletRequestWrapper; 10 /** 11 * @author 继承HttpServletRequestWrapper相当于实现了HttpServletRequest 12 * HttpServletRequestWrapper类,它本身实现了所有HttpServletRequest的方法 13 * 继承它之后,需要修改的方法MyRequest可以自己定义,不需要修改的方法,直接使用父类的方法 14 * 15 * 第一步:总结:继承HttpServletRequestWrapper,为了偷懒, 16 * 不用自己去实现所有HttpServletRequest的方法 第二步:使用构造函数将原来的request对象保存到当前自定义对象中 17 * 第三步:针对要修改的方法,进行增强 第四步:定义一个flag标记,防止编码重复执行 18 */ 19 public class MyRequest extends HttpServletRequestWrapper { 21 // 定义了一个成员变量,用来保存构造函数传入的requset对象 22 private HttpServletRequest request = null; 24 // 定义一个标记,用来标注:当前requset中,请求参数,是否已经编码过了 25 private boolean flag = false; 27 public MyRequest(HttpServletRequest request) { 28 super(request); 29 this.request = request; 31 } 33 // 总需求:对request对象的获取数据的方法,进行增强(统一编码) 35 @Override 36 public Map<String, String[]> getParameterMap() { 37 // 获得请求方式request.getMethod()方法 38 String method = this.request.getMethod(); 39 // post请求 40 if ("post".equalsIgnoreCase(method)) { 41 // 设置编码格式 42 try { 43 request.setCharacterEncoding("utf-8"); 44 } catch (UnsupportedEncodingException e) { 45 e.printStackTrace(); 46 } 47 Map<String, String[]> map = this.request.getParameterMap(); 48 return map; 50 } else if ("get".equalsIgnoreCase(method)) { 51 // get请求 52 // 分析:get请求需要对每一个参数都进行转换,因此需要对map中的每个元素进行遍历 53 // 首先获得map集合 54 Map<String, String[]> map = this.request.getParameterMap(); 56 //第一次获取请求参数,flag==false,执行后面的额乱码处理动作 57 //第二次获取请求参数的时候,flag==true,不执行后面的处理,直接返回已经编码过的map集合 58 if (flag) { 59 return map; 60 } 61 if (map == null) { 62 return super.getParameterMap(); 63 } else { 64 // 然后获得map集合的key 65 Set<String> key = map.keySet(); 66 // 通过key将map中的元素取出来 67 for (String string : key) { 68 String[] value = map.get(string); 69 // 接下来需要将String中的每一个都进行遍历,转换参数 70 for (int i = 0; i < value.length; i++) { 71 try { 72 String string2 = new String( 73 value[i].getBytes("iso-8859-1"), "utf-8"); 74 value[i] = string2; 75 } catch (UnsupportedEncodingException e) { 76 e.printStackTrace(); 77 } 78 } 79 } 80 flag = true; 81 return map; 82 } 83 } else { 84 //位置请求方式,自定义对象处理不了,使用父类的方法处理 85 return super.getParameterMap(); 86 } 87 } 89 @Override 90 public String[] getParameterValues(String name) { 91 // 通过map集合获取参数 92 Map<String, String[]> map = this.getParameterMap(); 93 if (map == null) { 94 return super.getParameterValues(name); 95 } else { 96 String[] strings = map.get(name); 97 return strings; 98 } 99 } 101 @Override 102 public String getParameter(String name) { 103 // 通过values获取参数 104 String[] values = this.getParameterValues(name); 105 if (values == null) { 106 return super.getParameter(name); 107 } else { 108 return values[0]; 109 } 110 } 112 } 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/6290284.html,如需转载请自行联系原作者

设计工具-MindManager(思维导图)

1,百度百科 http://baike.baidu.com/view/30054.htm?from_id=7153629&type=syn&fromtitle=MindManager&fr=aladdin 2,官方网站 http://www.mindjet.com/ 分类: 原型设计 本文转自ylbtech博客园博客,原文链接:http://www.cnblogs.com/ylbtech/p/4054496.html,如需转载请自行联系原作者

ylbtech-LanguageSamples-OfficeSample(COM 互操作)

ylbtech-Microsoft-CSharpSamples:ylbtech-LanguageSamples-OfficeSample(COM 互操作) 1.A,示例(Sample)返回顶部 本示例演示如何使用称为“COM 互操作”、“省略 ref”、“索引属性”、“命名参数”和“可选参数”的 C# 4.0 功能来创建与 Microsoft Office 进行通信的 C# 应用程序。 传统上,为了访问 Word、Excel 等 Microsoft Office 应用程序,C# 开发人员不得不编写相对冗长的代码。 新增的 C# 4.0 功能极大简化了对 Office API 的调用。 请看本示例中所用 Microsoft Office 方法的以下声明: void PasteSpecial(ref object IconIndex = null, ref object Link = null,      ref object Placement = null, ref object DisplayAsIcon = null,    ref object DataType = null, ref object IconFileName = null,     ref object IconLabel = null); 可以看到,此方法接受相当多的参数。 在 C# 中,开发人员传统上必须填写每个参数,即使进行这一调用的开发人员本欲通过支持可选参数来简化其使用也是如此。 在 C# 4.0 中,利用新增的对命名参数和可选参数的支持,开发人员可以仅指定所需参数,其他参数则使用其默认值: word.Selection.PasteSpecial(Link: true, DisplayAsIcon: true); 在对 PasteSpecial 方法的调用中,Link 和 DisplayAsIcon 参数是显式命名的,且设置为值 true。 所有其他参数都默认为 Office API 开发人员在内部指定的值,如上面的签名所示。 您可以创建自己的支持命名参数和可选参数的调用。 请看以下示例: public void M(int x, int y = 5, int z = 7) { } 在此方法中,为参数 y 和 z 分配了默认值。 对此方法的调用如下所示: M(1, 2, 3); // M 的普通调用 M(1, 2); // 省略 z,等效于 M(1, 2, 7) M(1);  // 同时省略 y 和 z,等效于 M(1, 5, 7) M(1, z: 3); // 通过名称传递 z M(x: 1, z: 3); // 通过名称同时传递 x 和 z M(z: 3, x: 1); // 反转实参的顺序 通过 C# 4.0 新增的动态功能,C# 开发人员可以更加方便地对 Office 编程。 现在,Office 中使用的类型可供 C# 开发人员调用,如同以 dynamic 类型对它们进行了声明一样。 下面是设置单元格属性的传统方式: ((Excel.Range)excel.Cells[1, 1]).Value2 = "ID"; 现在,在 C# 4.0 中,开发人员可以编写如下所示的代码: X1.Cells[1, 1].Value = "ID"; 借助索引属性功能,可以进一步简化调用,如下所示: xl.Cells[1, 1] = "ID"; 最后要介绍的是 No-PIA 功能,Office 开发人员一定会对它感兴趣。 主互操作程序集从 COM 接口生成,可在设计时提供有用的类型支持。 不过在运行时,这些程序集会增加程序的大小,可能导致版本控制问题。 利用 No-PIA 功能,可以继续在设计时使用 PIA,但在运行时省略 PIA。 C# 编译器将程序实际使用的小部分 PIA 直接复制到其程序集中。 您不再需要在程序的分发中包括 PIA。 1.B,示例代码(Sample Code)返回顶部 1.B.1, Program.cs  View Code 1.B.2, 1.C,下载地址(Free Download)返回顶部 本文转自ylbtech博客园博客,原文链接:http://www.cnblogs.com/ylbtech/p/4197055.html,如需转载请自行联系原作者

安装 Android SDK , 并更新; 打开命令行窗口, 输入下面的命令, 准备编译环境:  sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev sun-java6-jdk pngcrush schedtool  如果提示说找不到 sun-java-jdk , 可以安装 open-jdk6  代替; 安装 Repo 命令  curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo  chmod a+x ~/bin/repo 按照 nadlabak 的说明, 输入下列命令:  mkdir cm4mm  cd cm4mm  repo init -u git://github.com/nadlabak/android.git -b ics  repo sync  vendor/cm/get-prebuilts  . build/envsetup.sh && lunch cm_umts_sholes-eng && mka bacon 如果不出错误的话, 就可以在 out/target/product/umts_sholes 目录看到编译好的 update-cm-9.0.0-RC0-umts_sholes-UNOFFICIAL-signed.zip 文件, 这个文件可以通过 OpenRecovery 进行安装。 张志敏所有文章遵循创作共用版权协议,要求署名、非商业 、保持一致。在满足创作共用版权协议的基础上可以转载,但请以超链接形式注明出处。 本博客已经迁移到 GitHub , 围观地址: http://beginor.github.io/ #region 程序集 mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 // C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5.2\mscorlib.dll #endregion using System.Collections.Generic; using System.Diagnostics; using System.Runtime; using System.Runtime.CompilerServices; namespace System.Threading.Tasks // 摘要: // 表示一个异步操作。若要浏览此类型的.NET Framework 源代码,请参阅 Reference Source。 [DebuggerDisplay("Id = {Id}, Status = {Status}, Method = {DebuggerDisplayMethodDescription}")] [DebuggerTypeProxy(typeof(SystemThreadingTasks_TaskDebugView))] public class Task : IThreadPoolWorkItem, IAsyncResult, IDisposable // 摘要: // 使用指定的操作初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // 异常: // T:System.ArgumentNullException: // action 参数为 null。 public Task(Action action); // 摘要: // 使用指定的操作和 System.Threading.Tasks.Task 初始化新的 System.Threading.CancellationToken。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // cancellationToken: // 新任务将观察的 System.Threading.CancellationToken。 // 异常: // T:System.ObjectDisposedException: // 已释放提供的 System.Threading.CancellationToken。 // T:System.ArgumentNullException: // action 参数为 null。 public Task(Action action, CancellationToken cancellationToken); // 摘要: // 使用指定的操作和创建选项初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // creationOptions: // 用于自定义任务的行为的 System.Threading.Tasks.TaskCreationOptions。 // 异常: // T:System.ArgumentNullException: // action 参数为 null。 // T:System.ArgumentOutOfRangeException: // creationOptions 参数指定的值无效 System.Threading.Tasks.TaskCreationOptions。 public Task(Action action, TaskCreationOptions creationOptions); // 摘要: // 使用指定的操作和状态初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // state: // 一个表示由该操作使用的数据的对象。 // 异常: // T:System.ArgumentNullException: // action 参数为 null。 public Task(Action<object> action, object state); // 摘要: // 使用指定的操作和创建选项初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // cancellationToken: // 新任务将观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // creationOptions: // 用于自定义任务的行为的 System.Threading.Tasks.TaskCreationOptions。 // 异常: // T:System.ObjectDisposedException: // System.Threading.CancellationTokenSource 创建 cancellationToken 被释放。 // T:System.ArgumentNullException: // action 参数为 null。 // T:System.ArgumentOutOfRangeException: // creationOptions 参数指定的值无效 System.Threading.Tasks.TaskCreationOptions。 public Task(Action action, CancellationToken cancellationToken, TaskCreationOptions creationOptions); // 摘要: // 使用指定的操作、状态和选项初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // state: // 一个表示由该操作使用的数据的对象。 // cancellationToken: // 新任务将观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 异常: // T:System.ObjectDisposedException: // System.Threading.CancellationTokenSource 创建 cancellationToken 被释放。 // T:System.ArgumentNullException: // action 参数为 null。 public Task(Action<object> action, object state, CancellationToken cancellationToken); // 摘要: // 使用指定的操作、状态和选项初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // state: // 一个表示由该操作使用的数据的对象。 // creationOptions: // 用于自定义任务的行为的 System.Threading.Tasks.TaskCreationOptions。 // 异常: // T:System.ArgumentNullException: // action 参数为 null。 // T:System.ArgumentOutOfRangeException: // creationOptions 参数指定的值无效 System.Threading.Tasks.TaskCreationOptions。 public Task(Action<object> action, object state, TaskCreationOptions creationOptions); // 摘要: // 使用指定的操作、状态和选项初始化新的 System.Threading.Tasks.Task。 // 参数: // action: // 表示要在任务中执行的代码的委托。 // state: // 一个表示由该操作使用的数据的对象。 // cancellationToken: // 新任务将观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // creationOptions: // 用于自定义任务的行为的 System.Threading.Tasks.TaskCreationOptions。 // 异常: // T:System.ObjectDisposedException: // System.Threading.CancellationTokenSource 创建 cancellationToken 被释放。 // T:System.ArgumentNullException: // action 参数为 null。 // T:System.ArgumentOutOfRangeException: // creationOptions 参数指定的值无效 System.Threading.Tasks.TaskCreationOptions。 public Task(Action<object> action, object state, CancellationToken cancellationToken, TaskCreationOptions creationOptions); // 摘要: // 返回当前正在执行 System.Threading.Tasks.Task 的 ID。 // 返回结果: // 系统分配给当前正在执行的任务的一个整数。 public static int? CurrentId { get; } // 摘要: // 提供对用于创建 System.Threading.Tasks.Task 和 System.Threading.Tasks.Task`1 的工厂方法的访问。 // 返回结果: // 一个工厂对象,可创建多种 System.Threading.Tasks.Task 和 System.Threading.Tasks.Task`1 对象。 public static TaskFactory Factory { get; } // 摘要: // 获取此 System.Threading.Tasks.Task 是否已完成。 // 返回结果: // 如果任务已完成,则为 true;否则为 false。 public bool IsCompleted { get; } // 摘要: // 获取此 System.Threading.Tasks.Task 实例是否由于被取消的原因而已完成执行。 // 返回结果: // 如果任务由于被取消而完成,则为 true;否则为 false。 public bool IsCanceled { get; } // 摘要: // 获取此任务的 System.Threading.Tasks.TaskStatus。 // 返回结果: // 此任务实例的当前 System.Threading.Tasks.TaskStatus。 public TaskStatus Status { get; } // 摘要: // 获取导致 System.AggregateException 提前结束的 System.Threading.Tasks.Task。 如果 System.Threading.Tasks.Task // 成功完成或尚未引发任何异常,这将返回 null。 // 返回结果: // 导致 System.AggregateException 提前结束的 System.Threading.Tasks.Task。 public AggregateException Exception { get; } // 摘要: // 获取此 System.Threading.Tasks.Task 实例的 ID。 // 返回结果: // 系统分配到此 System.Threading.Tasks.Task 实例的标识符。 public int Id { get; } // 摘要: // 获取用于创建此任务的 System.Threading.Tasks.TaskCreationOptions。 // 返回结果: // 用于创建此任务的 System.Threading.Tasks.TaskCreationOptions。 public TaskCreationOptions CreationOptions { get; } // 摘要: // 获取在创建 System.Threading.Tasks.Task 时提供的状态对象,如果未提供,则为 null。 // 返回结果: // 一个 System.Object,表示在创建任务时传递给该任务的状态数据。 public object AsyncState { get; } // 摘要: // 获取 System.Threading.Tasks.Task 是否由于未经处理异常的原因而完成。 // 返回结果: // 如果任务引发了未经处理的异常,则为 true;否则为 false。 public bool IsFaulted { get; } // 摘要: // 创建一个在指定的时间间隔后完成的任务。 // 参数: // delay: // 在完成返回的任务前等待的时间跨度;如果无限期等待,则为 TimeSpan.FromMilliseconds(-1)。 // 返回结果: // 表示时间延迟的任务。 // 异常: // T:System.ArgumentOutOfRangeException: // delay 表示负时间间隔以外 TimeSpan.FromMillseconds(-1)。- 或 -delay 参数的 System.TimeSpan.TotalMilliseconds // 属性大于 System.Int32.MaxValue。 public static Task Delay(TimeSpan delay); // 摘要: // 创建一个在指定的时间间隔后完成的可取消任务。 // 参数: // delay: // 在完成返回的任务前等待的时间跨度;如果无限期等待,则为 TimeSpan.FromMilliseconds(-1)。 // cancellationToken: // 将在完成返回的任务之前选中的取消标记。 // 返回结果: // 表示时间延迟的任务。 // 异常: // T:System.ArgumentOutOfRangeException: // delay 表示负时间间隔以外 TimeSpan.FromMillseconds(-1)。- 或 -delay 参数的 System.TimeSpan.TotalMilliseconds // 属性大于 System.Int32.MaxValue。 // T:System.Threading.Tasks.TaskCanceledException: // 该任务已取消。 // T:System.ObjectDisposedException: // 提供 cancellationToken 被释放。 public static Task Delay(TimeSpan delay, CancellationToken cancellationToken); // 摘要: // 创建将在时间延迟后完成的任务。 // 参数: // millisecondsDelay: // 在完成返回的任务前要等待的毫秒数;如果无限期等待,则为 -1。 // 返回结果: // 表示时间延迟的任务。 // 异常: // T:System.ArgumentOutOfRangeException: // millisecondsDelay 参数是小于-1。 public static Task Delay(int millisecondsDelay); // 摘要: // 创建将在时间延迟后完成的可取消任务。 // 参数: // millisecondsDelay: // 在完成返回的任务前要等待的毫秒数;如果无限期等待,则为 -1。 // cancellationToken: // 将在完成返回的任务之前选中的取消标记。 // 返回结果: // 表示时间延迟的任务。 // 异常: // T:System.ArgumentOutOfRangeException: // millisecondsDelay 参数是小于-1。 // T:System.Threading.Tasks.TaskCanceledException: // 该任务已取消。 // T:System.ObjectDisposedException: // 提供 cancellationToken 被释放。 public static Task Delay(int millisecondsDelay, CancellationToken cancellationToken); // 摘要: // 创建指定结果的、成功完成的 System.Threading.Tasks.Task`1。 // 参数: // result: // 存储入已完成任务的结果。 // 类型参数: // TResult: // 任务返回的结果的类型。 // 返回结果: // 已成功完成的任务。 public static Task<TResult> FromResult<TResult>(TResult result); // 摘要: // 将在线程池上运行的指定工作排队,并返回 function 所返回的任务的代理项。 // 参数: // function: // 以异步方式执行的工作。 // cancellationToken: // 应用以取消工作的取消标记。 // 返回结果: // 表示由 function 返回的任务代理的任务。 // 异常: // T:System.ArgumentNullException: // function 参数为 null。 // T:System.Threading.Tasks.TaskCanceledException: // 该任务已取消。 // T:System.ObjectDisposedException: // 与 cancellationToken 关联的 System.Threading.CancellationTokenSource 已释放。 public static Task Run(Func<Task> function, CancellationToken cancellationToken); // 摘要: // 将在线程池上运行的指定工作排队,并返回 function 所返回的任务的代理。 // 参数: // function: // 以异步方式执行的工作量。 // 返回结果: // 表示由 function 返回的任务代理的任务。 // 异常: // T:System.ArgumentNullException: // function 参数是 null。 public static Task Run(Func<Task> function); // 摘要: // 将在线程池上运行的指定工作排队,并返回代表该工作的 System.Threading.Tasks.Task 对象。 可使用取消标记来取消工作。 // 参数: // action: // 以异步方式执行的工作量。 // cancellationToken: // 可用于取消工作的取消标记 // 返回结果: // 一个任务,它表示在线程池中排队等待执行的工作。 // 异常: // T:System.ArgumentNullException: // action 参数为 null。 // T:System.Threading.Tasks.TaskCanceledException: // 该任务已取消。 // T:System.ObjectDisposedException: // 已释放与 cancellationToken 关联的 System.Threading.CancellationTokenSource。 public static Task Run(Action action, CancellationToken cancellationToken); // 摘要: // 在线程池上运行的指定的工作排队,并返回的代理 Task(TResult) 返回 function。 // 参数: // function: // 以异步方式执行的工作量。 // 类型参数: // TResult: // 代理任务返回的结果的类型。 // 返回结果: // 表示由 Task(TResult) 返回的 Task(TResult) 的代理的 function。 // 异常: // T:System.ArgumentNullException: // function 参数是 null。 public static Task<TResult> Run<TResult>(Func<Task<TResult>> function); // 摘要: // 在线程池上运行的指定的工作排队,并返回的代理 Task(TResult) 返回 function。 // 参数: // function: // 以异步方式执行的工作量。 // cancellationToken: // 应用以取消工作的取消标记 // 类型参数: // TResult: // 代理任务返回的结果的类型。 // 返回结果: // 表示由 Task(TResult) 返回的 Task(TResult) 的代理的 function。 // 异常: // T:System.ArgumentNullException: // function 参数是 null。 // T:System.Threading.Tasks.TaskCanceledException: // 该任务已取消。 // T:System.ObjectDisposedException: // 与 cancellationToken 关联的 System.Threading.CancellationTokenSource 已释放。 public static Task<TResult> Run<TResult>(Func<Task<TResult>> function, CancellationToken cancellationToken); // 摘要: // 将在线程池上运行的指定工作排队,并返回代表该工作的 System.Threading.Tasks.Task 对象。 // 参数: // action: // 以异步方式执行的工作量。 // 返回结果: // 表示在线程池执行的队列的任务。 // 异常: // T:System.ArgumentNullException: // action 参数是 null。 public static Task Run(Action action); // 摘要: // 将在线程池上运行的指定工作排队,并返回代表该工作的 Task(TResult) 对象。 借助取消标记,可取消工作。 // 参数: // function: // 以异步方式执行的工作量。 // cancellationToken: // 应用以取消工作的取消标记 // 类型参数: // TResult: // 任务的结果类型。 // 返回结果: // 一个 Task(TResult),它表示在线程池中排队等待执行的工作。 // 异常: // T:System.ArgumentNullException: // function 参数为 null。 // T:System.Threading.Tasks.TaskCanceledException: // 该任务已取消。 // T:System.ObjectDisposedException: // 与 cancellationToken 关联的 System.Threading.CancellationTokenSource 已释放。 public static Task<TResult> Run<TResult>(Func<TResult> function, CancellationToken cancellationToken); // 摘要: // 将在线程池上运行的指定工作排队,并返回代表该工作的 System.Threading.Tasks.Task`1 对象。 // 参数: // function: // 以异步方式执行的工作。 // 类型参数: // TResult: // 任务的返回类型。 // 返回结果: // 表示在线程池中排队执行的工作的任务对象。 // 异常: // T:System.ArgumentNullException: // function 参数为 null。 public static Task<TResult> Run<TResult>(Func<TResult> function); // 摘要: // 等待提供的所有 System.Threading.Tasks.Task 对象完成执行过程。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // 异常: // T:System.ObjectDisposedException: // tasks 中的一个或多个 System.Threading.Tasks.Task 对象已释放。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。- 或 -tasks 参数为空数组。 // T:System.AggregateException: // 至少一个 System.Threading.Tasks.Task 实例已取消。 如果任务已被取消, System.AggregateException 异常将包含 // System.OperationCanceledException 中的异常其 System.AggregateException.InnerExceptions // 集合。- 或 -在至少一个 System.Threading.Tasks.Task 实例的执行过程中引发了异常。 public static void WaitAll(params Task[] tasks); // 摘要: // 等待所有提供的可取消 System.Threading.Tasks.Task 对象在指定的时间间隔内完成执行。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // timeout: // 表示等待毫秒数的 System.TimeSpan,或表示 -1 毫秒(无限期等待)的 System.TimeSpan。 // 返回结果: // 如果在分配的时间内所有 true 实例都已完成执行,则为 System.Threading.Tasks.Task;否则为 false。 // 异常: // T:System.ObjectDisposedException: // tasks 中的一个或多个 System.Threading.Tasks.Task 对象已释放。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.AggregateException: // 至少一个 System.Threading.Tasks.Task 实例已取消。 如果任务已取消,则 System.AggregateException 在其 // System.AggregateException.InnerExceptions 集合中包含 System.OperationCanceledException。- // 或 -在至少一个 System.Threading.Tasks.Task 实例的执行过程中引发了异常。 // T:System.ArgumentOutOfRangeException: // timeout 为 -1 毫秒以外的负数,表示无限期超时。- 或 -timeout 大于 System.Int32.MaxValue。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。- 或 -tasks 参数为空数组。 public static bool WaitAll(Task[] tasks, TimeSpan timeout); // 摘要: // 等待所有提供的 System.Threading.Tasks.Task 在指定的毫秒数内完成执行。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // millisecondsTimeout: // 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 // 返回结果: // 如果在分配的时间内所有 true 实例都已完成执行,则为 System.Threading.Tasks.Task;否则为 false。 // 异常: // T:System.ObjectDisposedException: // tasks 中的一个或多个 System.Threading.Tasks.Task 对象已释放。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.AggregateException: // 至少一个 System.Threading.Tasks.Task 实例已取消。 如果任务已取消,则 System.AggregateException 在其 // System.AggregateException.InnerExceptions 集合中包含 System.OperationCanceledException。- // 或 -在至少一个 System.Threading.Tasks.Task 实例的执行过程中引发了异常。 // T:System.ArgumentOutOfRangeException: // millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。- 或 -tasks 参数为空数组。 public static bool WaitAll(Task[] tasks, int millisecondsTimeout); // 摘要: // 等待提供的所有 System.Threading.Tasks.Task 对象完成执行过程(除非取消等待)。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // cancellationToken: // 等待任务完成期间要观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 异常: // T:System.OperationCanceledException: // cancellationToken 已取消。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.AggregateException: // 至少一个 System.Threading.Tasks.Task 实例已取消。 如果任务已取消,则 System.AggregateException 在其 // System.AggregateException.InnerExceptions 集合中包含 System.OperationCanceledException。- // 或 -在至少一个 System.Threading.Tasks.Task 实例的执行过程中引发了异常。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。- 或 -tasks 参数为空数组。 // T:System.ObjectDisposedException: // tasks 中的一个或多个 System.Threading.Tasks.Task 对象已释放。 public static void WaitAll(Task[] tasks, CancellationToken cancellationToken); // 摘要: // 等待提供的所有 System.Threading.Tasks.Task 对象在指定的毫秒数内完成执行,或等到取消等待。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // millisecondsTimeout: // 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 // cancellationToken: // 等待任务完成期间要观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 返回结果: // 如果在分配的时间内所有 true 实例都已完成执行,则为 System.Threading.Tasks.Task;否则为 false。 // 异常: // T:System.ObjectDisposedException: // tasks 中的一个或多个 System.Threading.Tasks.Task 对象已释放。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.AggregateException: // 至少一个 System.Threading.Tasks.Task 实例已取消。 如果任务已取消,则 System.AggregateException 在其 // System.AggregateException.InnerExceptions 集合中包含 System.OperationCanceledException。- // 或 -在至少一个 System.Threading.Tasks.Task 实例的执行过程中引发了异常。 // T:System.ArgumentOutOfRangeException: // millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。- 或 -tasks 参数为空数组。 // T:System.OperationCanceledException: // cancellationToken 已取消。 public static bool WaitAll(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken); // 摘要: // 等待提供的任一 System.Threading.Tasks.Task 对象完成执行过程。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // 返回结果: // tasks 数组中已完成的 System.Threading.Tasks.Task 对象的所有。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。 public static int WaitAny(params Task[] tasks); // 摘要: // 等待任何提供的 System.Threading.Tasks.Task 对象在指定的时间间隔内完成执行。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // timeout: // 表示等待毫秒数的 System.TimeSpan,或表示 -1 毫秒(无限期等待)的 System.TimeSpan。 // 返回结果: // 已完成的任务在 tasks 数组参数中的索引,如果发生超时,则为 -1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentOutOfRangeException: // timeout 为 -1 毫秒以外的负数,表示无限期超时。- 或 -timeout 大于 System.Int32.MaxValue。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。 public static int WaitAny(Task[] tasks, TimeSpan timeout); // 摘要: // 等待任何提供的 System.Threading.Tasks.Task 对象在指定的毫秒数内完成执行。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // millisecondsTimeout: // 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 // 返回结果: // 已完成的任务在 tasks 数组参数中的索引,如果发生超时,则为 -1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentOutOfRangeException: // millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。 public static int WaitAny(Task[] tasks, int millisecondsTimeout); // 摘要: // 等待提供的任何 System.Threading.Tasks.Task 对象完成执行过程(除非取消等待)。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // cancellationToken: // 等待任务完成期间要观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 返回结果: // 已完成的任务在 tasks 数组参数中的索引。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。 // T:System.OperationCanceledException: // cancellationToken 已取消。 public static int WaitAny(Task[] tasks, CancellationToken cancellationToken); // 摘要: // 等待提供的任何 System.Threading.Tasks.Task 对象在指定的毫秒数内完成执行,或等到取消标记取消。 // 参数: // tasks: // 要等待的 System.Threading.Tasks.Task 实例的数组。 // millisecondsTimeout: // 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 // cancellationToken: // 等待任务完成期间要观察的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 返回结果: // 已完成的任务在 tasks 数组参数中的索引,如果发生超时,则为 -1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentOutOfRangeException: // millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。 // T:System.ArgumentException: // tasks 参数包含一个 null 元素。 // T:System.OperationCanceledException: // cancellationToken 已取消。 public static int WaitAny(Task[] tasks, int millisecondsTimeout, CancellationToken cancellationToken); // 摘要: // 创建一个任务,该任务将在可枚举集合中的所有 System.Threading.Tasks.Task 对象都完成时完成。 // 参数: // tasks: // 等待完成的任务。 // 返回结果: // 表示所有提供的任务的完成情况的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // 此 tasks 集合包含 null 任务。 public static Task WhenAll(IEnumerable<Task> tasks); // 摘要: // 创建一个任务,该任务将在数组中的所有 System.Threading.Tasks.Task 对象都完成时完成。 // 参数: // tasks: // 等待完成的任务。 // 返回结果: // 表示所有提供的任务的完成情况的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 数组包含 null 任务。 public static Task WhenAll(params Task[] tasks); // 摘要: // 创建一个任务,该任务将在可枚举集合中的所有 System.Threading.Tasks.Task`1 对象都完成时完成。 // 参数: // tasks: // 等待完成的任务。 // 类型参数: // TResult: // 已完成任务的类型。 // 返回结果: // 表示所有提供的任务的完成情况的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // 此 tasks 集合包含 null 任务。 public static Task<TResult[]> WhenAll<TResult>(IEnumerable<Task<TResult>> tasks); // 摘要: // 创建一个任务,该任务将在数组中的所有 System.Threading.Tasks.Task`1 对象都完成时完成。 // 参数: // tasks: // 等待完成的任务。 // 类型参数: // TResult: // 已完成任务的类型。 // 返回结果: // 表示所有提供的任务的完成情况的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 数组包含 null 任务。 public static Task<TResult[]> WhenAll<TResult>(params Task<TResult>[] tasks); // 摘要: // 任何提供的任务已完成时,创建将完成的任务。 // 参数: // tasks: // 等待完成的任务。 // 返回结果: // 表示提供的任务之一已完成的任务。 返回任务的结果是完成的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为空。 // T:System.ArgumentException: // tasks 数组包含 null 任务,或者为空。 public static Task<Task> WhenAny(params Task[] tasks); // 摘要: // 任何提供的任务已完成时,创建将完成的任务。 // 参数: // tasks: // 等待完成的任务。 // 返回结果: // 表示提供的任务之一已完成的任务。 返回任务的结果是完成的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 数组包含 null 任务,或者为空。 public static Task<Task> WhenAny(IEnumerable<Task> tasks); // 摘要: // 任何提供的任务已完成时,创建将完成的任务。 // 参数: // tasks: // 等待完成的任务。 // 类型参数: // TResult: // 已完成任务的类型。 // 返回结果: // 表示提供的任务之一已完成的任务。 返回任务的结果是完成的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为空。 // T:System.ArgumentException: // tasks 数组包含 null 任务,或者为空。 public static Task<Task<TResult>> WhenAny<TResult>(params Task<TResult>[] tasks); // 摘要: // 任何提供的任务已完成时,创建将完成的任务。 // 参数: // tasks: // 等待完成的任务。 // 类型参数: // TResult: // 已完成任务的类型。 // 返回结果: // 表示提供的任务之一已完成的任务。 返回任务的结果是完成的任务。 // 异常: // T:System.ArgumentNullException: // tasks 参数为 null。 // T:System.ArgumentException: // tasks 数组包含 null 任务,或者为空。 public static Task<Task<TResult>> WhenAny<TResult>(IEnumerable<Task<TResult>> tasks); // 摘要: // 创建异步产生当前上下文的等待任务。 // 返回结果: // 等待时,上下文将异步转换回等待时的当前上下文。 如果当前 System.Threading.SynchronizationContext 不为 null,则将其视为当前上下文。 // 否则,与当前执行任务关联的任务计划程序将视为当前上下文。 public static YieldAwaitable Yield(); // 摘要: // 配置用于等待此 System.Threading.Tasks.Task的 awaiter。 // 参数: // continueOnCapturedContext: // 尝试将延续任务封送回原始上下文,则为 true;否则为 false。 // 返回结果: // 用于的等待此任务的对象。 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public ConfiguredTaskAwaitable ConfigureAwait(bool continueOnCapturedContext); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成并返回一个值时根据指定的任务延续选项执行的延续任务。 延续任务接收调用方提供的状态信息和取消标记,并使用指定计划程序。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续功能使用的数据的对象。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.CancellationToken。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ArgumentNullException: // continuationFunction 参数为 null。 // T:System.ArgumentNullException: // scheduler 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 // T:System.ObjectDisposedException: // 提供 System.Threading.CancellationToken 被释放。 public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时根据指定的任务延续选项执行的延续任务。 延续任务接收调用方提供的状态信息。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续功能使用的数据的对象。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ArgumentNullException: // continuationFunction 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskContinuationOptions continuationOptions); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时异步执行的延续任务。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 在运行时,委托将作为一个参数传递给完成的任务。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 public Task ContinueWith(Action<Task> continuationAction); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时可接收取消标记并以异步方式执行的延续任务。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 在运行时,委托将作为一个参数传递给完成的任务。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ObjectDisposedException: // System.Threading.CancellationTokenSource 创建该标记已被释放。 // T:System.ArgumentNullException: // continuationAction 参数为 null。 public Task ContinueWith(Action<Task> continuationAction, CancellationToken cancellationToken); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时异步执行的延续任务。 延续任务使用指定计划程序。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 在运行时,委托将作为一个参数传递给完成的任务。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // continuationAction 参数为 null。- 或 -scheduler 参数为 null。 public Task ContinueWith(Action<Task> continuationAction, TaskScheduler scheduler); // 摘要: // 创建一个在目标任务完成时按照指定的 System.Threading.Tasks.TaskContinuationOptions 执行的延续任务。 延续任务会收到一个取消标记,并使用指定计划程序。 // 参数: // continuationAction: // 根据在 continuationOptions 中指定的条件运行的操作。 在运行时,委托将作为一个参数传递给完成的任务。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.Tasks.TaskFactory.CancellationToken。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ObjectDisposedException: // System.Threading.CancellationTokenSource 创建该标记已被释放。 // T:System.ArgumentNullException: // continuationAction 参数为 null。- 或 -scheduler 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 public Task ContinueWith(Action<Task> continuationAction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时接收调用方提供的状态信息并执行的延续任务。 // 参数: // continuationAction: // 在任务完成时要运行的操作。 运行时,委托作为一个参数传递给完成的任务和调用方提供的状态对象。 // state: // 一个表示由该延续操作使用的数据的对象。 // 返回结果: // 一个新的延续任务。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 public Task ContinueWith(Action<Task, object> continuationAction, object state); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时接收调用方提供的状态信息和取消标记,并以异步方式执行的延续任务。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续操作使用的数据的对象。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.CancellationToken。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 // T:System.ObjectDisposedException: // 提供 System.Threading.CancellationToken 被释放。 public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时接收调用方提供的状态信息并以异步方式执行的延续任务。 延续任务使用指定计划程序。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续操作使用的数据的对象。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 // T:System.ArgumentNullException: // scheduler 参数为 null。 public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskScheduler scheduler); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时接收调用方提供的状态信息并执行的延续任务。 延续任务根据一组指定的条件执行。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续操作使用的数据的对象。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 public Task ContinueWith(Action<Task, object> continuationAction, object state, TaskContinuationOptions continuationOptions); // 摘要: // 创建一个在目标任务完成时按照指定的 System.Threading.Tasks.TaskContinuationOptions 执行的延续任务。 // 参数: // continuationAction: // 根据在 continuationOptions 中指定的条件运行的操作。 在运行时,委托将作为一个参数传递给完成的任务。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 public Task ContinueWith(Action<Task> continuationAction, TaskContinuationOptions continuationOptions); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task`1 完成时异步执行并返回一个值的延续任务。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task`1 完成时要运行的函数。 在运行时,委托将作为一个参数传递给完成的任务。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续任务。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // continuationFunction 参数为 null。 public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成并返回一个值时异步执行的延续任务。 延续任务收到取消标记。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 在运行时,委托将作为一个参数传递给完成的任务。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.Tasks.TaskFactory.CancellationToken。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。- 或 -System.Threading.CancellationTokenSource // 创建该标记已被释放。 // T:System.ArgumentNullException: // continuationFunction 参数为 null。 public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, CancellationToken cancellationToken); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时异步执行并返回一个值的延续任务。 延续任务使用指定计划程序。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 在运行时,委托将作为一个参数传递给完成的任务。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // continuationFunction 参数为 null。- 或 -scheduler 参数为 null。 public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, TaskScheduler scheduler); // 摘要: // 创建一个按照指定延续任务选项执行并返回一个值的延续任务。 // 参数: // continuationFunction: // 根据在 continuationOptions 中指定的条件运行的函数。 在运行时,委托将作为一个参数传递给完成的任务。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentNullException: // continuationFunction 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, TaskContinuationOptions continuationOptions); // 摘要: // 创建一个按照指定延续任务选项执行并返回一个值的延续任务。 延续任务被传入一个取消标记,并使用指定计划程序。 // 参数: // continuationFunction: // 根据 continuationOptions. 中指定的条件运行函数。在运行时,委托将作为一个自变量传递给完成的任务。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.Tasks.TaskFactory.CancellationToken。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。- 或 -System.Threading.CancellationTokenSource // 创建该标记已被释放。 // T:System.ArgumentNullException: // continuationFunction 参数为 null。- 或 -scheduler 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 public Task<TResult> ContinueWith<TResult>(Func<Task, TResult> continuationFunction, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成并返回一个值时接收调用方提供的状态信息并以异步方式执行的延续任务。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续功能使用的数据的对象。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ArgumentNullException: // continuationFunction 参数为 null。 public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时异步执行并返回一个值的延续任务。 延续任务接收调用方提供的状态信息和取消标记。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续功能使用的数据的对象。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.CancellationToken。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ArgumentNullException: // continuationFunction 参数为 null。 // T:System.ObjectDisposedException: // 提供 System.Threading.CancellationToken 被释放。 public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, CancellationToken cancellationToken); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时异步执行的延续任务。 延续任务接收调用方提供的状态信息,并使用指定计划程序。 // 参数: // continuationFunction: // 在 System.Threading.Tasks.Task 完成时要运行的函数。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续功能使用的数据的对象。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 类型参数: // TResult: // 延续任务生成的结果的类型。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task`1。 // 异常: // T:System.ArgumentNullException: // continuationFunction 参数为 null。 // T:System.ArgumentNullException: // scheduler 参数为 null。 public Task<TResult> ContinueWith<TResult>(Func<Task, object, TResult> continuationFunction, object state, TaskScheduler scheduler); // 摘要: // 创建一个在目标 System.Threading.Tasks.Task 完成时接收调用方提供的状态信息和取消标记并执行的延续任务。 延续任务根据一组指定的条件执行,并使用指定的计划程序。 // 参数: // continuationAction: // 在 System.Threading.Tasks.Task 完成时要运行的操作。 运行时,将传递委托,如完成的任务一样,调用方提供的状态对象(如参数)。 // state: // 一个表示由该延续操作使用的数据的对象。 // cancellationToken: // 将指派给新的延续任务的 System.Threading.CancellationToken。 // continuationOptions: // 用于设置计划延续任务的时间以及延续任务的工作方式的选项。 这包括条件(如 System.Threading.Tasks.TaskContinuationOptions.OnlyOnCanceled)和执行选项(如 // System.Threading.Tasks.TaskContinuationOptions.ExecuteSynchronously)。 // scheduler: // 要与延续任务关联并用于其执行过程的 System.Threading.Tasks.TaskScheduler。 // 返回结果: // 一个新的延续 System.Threading.Tasks.Task。 // 异常: // T:System.ArgumentNullException: // continuationAction 参数为 null。 // T:System.ArgumentNullException: // scheduler 参数为 null。 // T:System.ArgumentOutOfRangeException: // continuationOptions 参数指定的值无效 System.Threading.Tasks.TaskContinuationOptions。 // T:System.ObjectDisposedException: // 提供 System.Threading.CancellationToken 被释放。 public Task ContinueWith(Action<Task, object> continuationAction, object state, CancellationToken cancellationToken, TaskContinuationOptions continuationOptions, TaskScheduler scheduler); // 摘要: // 释放 System.Threading.Tasks.Task 类的当前实例所使用的所有资源。 // 异常: // T:System.InvalidOperationException: // 任务未处于最终状态之一 ︰ System.Threading.Tasks.TaskStatus.RanToCompletion, ,System.Threading.Tasks.TaskStatus.Faulted, // ,或 System.Threading.Tasks.TaskStatus.Canceled。 public void Dispose(); // 摘要: // 获取用于等待此 System.Threading.Tasks.Task 的 awaiter。 // 返回结果: // 一个 awaiter 实例。 [TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")] public TaskAwaiter GetAwaiter(); // 摘要: // 对当前的 System.Threading.Tasks.Task 同步运行 System.Threading.Tasks.TaskScheduler。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task 实例。 // T:System.InvalidOperationException: // System.Threading.Tasks.Task 并非要启动的有效状态。 它可能已启动、执行或取消,或者它可能是以不支持直接计划的方式创建的。 public void RunSynchronously(); // 摘要: // 对提供的 System.Threading.Tasks.Task 同步运行 System.Threading.Tasks.TaskScheduler。 // 参数: // scheduler: // 尝试对其以内联方式运行此任务的计划程序。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task 实例。 // T:System.ArgumentNullException: // scheduler 参数为 null。 // T:System.InvalidOperationException: // System.Threading.Tasks.Task 并非要启动的有效状态。 它可能已启动、执行或取消,或者它可能是以不支持直接计划的方式创建的。 public void RunSynchronously(TaskScheduler scheduler); // 摘要: // 启动 System.Threading.Tasks.Task,并将它安排到当前的 System.Threading.Tasks.TaskScheduler // 中执行。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task 实例。 // T:System.InvalidOperationException: // System.Threading.Tasks.Task 并非要启动的有效状态。 它可能已启动、执行或取消,或者它可能是以不支持直接计划的方式创建的。 public void Start(); // 摘要: // 启动 System.Threading.Tasks.Task,并将它安排到指定的 System.Threading.Tasks.TaskScheduler // 中执行。 // 参数: // scheduler: // 要与之关联并执行此任务的 System.Threading.Tasks.TaskScheduler。 // 异常: // T:System.ArgumentNullException: // scheduler 参数为 null。 // T:System.InvalidOperationException: // System.Threading.Tasks.Task 并非要启动的有效状态。 它可能已启动、执行或取消,或者它可能是以不支持直接计划的方式创建的。 // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task 实例。 // T:System.Threading.Tasks.TaskSchedulerException: // 计划程序无法将此任务进行排队。 public void Start(TaskScheduler scheduler); // 摘要: // 等待 System.Threading.Tasks.Task 在指定的毫秒数内完成执行。 // 参数: // millisecondsTimeout: // 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 // 返回结果: // 如果在分配的时间内 true 完成执行,则为 System.Threading.Tasks.Task;否则为 false。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentOutOfRangeException: // millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。 // T:System.AggregateException: // 任务已取消。System.AggregateException.InnerExceptions 集合包含 System.Threading.Tasks.TaskCanceledException // 对象。- 或 -该任务的执行过程中引发异常。System.AggregateException.InnerExceptions 集合包含有关异常或异常的信息。 public bool Wait(int millisecondsTimeout); // 摘要: // 等待 System.Threading.Tasks.Task 完成执行过程。 如果在任务完成之前取消标记已取消,等待将终止。 // 参数: // cancellationToken: // 等待任务完成期间要观察的取消标记。 // 异常: // T:System.OperationCanceledException: // cancellationToken 已取消。 // T:System.ObjectDisposedException: // 该任务已被释放。 // T:System.AggregateException: // 任务已取消。System.AggregateException.InnerExceptions 集合包含 System.Threading.Tasks.TaskCanceledException // 对象。- 或 -该任务的执行过程中引发异常。System.AggregateException.InnerExceptions 集合包含有关异常或异常的信息。 public void Wait(CancellationToken cancellationToken); // 摘要: // 等待 System.Threading.Tasks.Task 完成执行过程。 如果在任务完成之前超时间隔结束或取消标记已取消,等待将终止。 // 参数: // millisecondsTimeout: // 等待的毫秒数,或为 System.Threading.Timeout.Infinite (-1),表示无限期等待。 // cancellationToken: // 等待任务完成期间要观察的取消标记。 // 返回结果: // 如果在分配的时间内 true 完成执行,则为 System.Threading.Tasks.Task;否则为 false。 // 异常: // T:System.OperationCanceledException: // cancellationToken 已取消。 // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentOutOfRangeException: // millisecondsTimeout 是一个非 -1 的负数,而 -1 表示无限期超时。 // T:System.AggregateException: // 任务已取消。System.AggregateException.InnerExceptions 集合包含 System.Threading.Tasks.TaskCanceledException // 对象。- 或 -该任务的执行过程中引发异常。System.AggregateException.InnerExceptions 集合包含有关异常或异常的信息。 public bool Wait(int millisecondsTimeout, CancellationToken cancellationToken); // 摘要: // 等待 System.Threading.Tasks.Task 完成执行过程。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.AggregateException: // 任务已取消。System.AggregateException.InnerExceptions 集合包含 System.Threading.Tasks.TaskCanceledException // 对象。- 或 -该任务的执行过程中引发异常。System.AggregateException.InnerExceptions 集合包含有关异常或异常的信息。 public void Wait(); // 摘要: // 等待 System.Threading.Tasks.Task 在指定的时间间隔内完成执行。 // 参数: // timeout: // 表示等待毫秒数的 System.TimeSpan,或表示 -1 毫秒(无限期等待)的 System.TimeSpan。 // 返回结果: // 如果在分配的时间内 true 完成执行,则为 System.Threading.Tasks.Task;否则为 false。 // 异常: // T:System.ObjectDisposedException: // 已释放了 System.Threading.Tasks.Task。 // T:System.ArgumentOutOfRangeException: // timeout 为 -1 毫秒以外的负数,表示无限期超时。- 或 -timeout 大于 System.Int32.MaxValue。 // T:System.AggregateException: // 任务已取消。System.AggregateException.InnerExceptions 集合包含 System.Threading.Tasks.TaskCanceledException // 对象。- 或 -该任务的执行过程中引发异常。System.AggregateException.InnerExceptions 集合包含有关异常或异常的信息。 public bool Wait(TimeSpan timeout); // 摘要: // 释放 System.Threading.Tasks.Task,同时释放其所有非托管资源。 // 参数: // disposing: // 一个布尔值,该值指示是否由于调用 System.Threading.Tasks.Task.Dispose 的原因而调用此方法。 // 异常: // T:System.InvalidOperationException: // 任务未处于最终状态之一 ︰ System.Threading.Tasks.TaskStatus.RanToCompletion, ,System.Threading.Tasks.TaskStatus.Faulted, // ,或 System.Threading.Tasks.TaskStatus.Canceled。 protected virtual void Dispose(bool disposing); 2.返回顶部 3.返回顶部 4.返回顶部 5.返回顶部 6.返回顶部 7.返回顶部 8.返回顶部 9.返回顶部 10. 相关资源返回顶部 https://msdn.microsoft.com/zh-cn/library/system.threading.tasks.task.aspx 11.返回顶部 本文转自ylbtech博客园博客,原文链接:http://www.cnblogs.com/ylbtech/p/8110241.html,如需转载请自行联系原作者

微信公众平台开发之微信access_token如何有效长期保存

随着微信使用越来越广泛,微信公众平台开放了许多接口以提供更多个性化的服务,包括自定义菜单接口、客服接口、获取用户信息接口、用户分组接口、群发接口等,开发者在调用这些接口时,都需要传入一个相同的参数access_token,它是公众账号的全局唯一票据,它是接口访问凭证。 access_token的有效期是7200秒(两小时),在有效期内可以使用,一旦access_token过期,需要重新通过调用微信接口获取。目前微信接口上面获取access_token每日限额为2000次,如果每次创建菜单,发送主动消息,获取用户信息,群发信息之前都去获取,必然会达到该接口的频率限制,在实际微信接口开发中,我们需要把获取到的access_token存储起来,然后设置有效期,在有效期过期后再去获取,以保证access_token实时的有效性。 下面是自己想到的一种xml的存储方式,直接贴代码:      public string GetExistAccessToken()             // 读取XML文件中的数据             string filepath = Server.MapPath("/File/XMLToken.xml");             StreamReader str = new StreamReader(filepath, System.Text.Encoding.UTF8);             XmlDocument xml = new XmlDocument();             xml.Load(str);             str.Close();             str.Dispose();            stringToken=xml.SelectSingleNode("xml").SelectSingleNode("AccessToken").InnerText;            DateTime AccessExpires =Convert.ToDateTime(xml.SelectSingleNode("xml").SelectSingleNode("AccessExpires").InnerText);             if (DateTime.Now >= AccessExpires)                 Access_token mode = GetAccessToken();                xml.SelectSingleNode("xml").SelectSingleNode("AccessToken").InnerText = mode.access_token;                 DateTime _accessExpires =DateTime.Now.AddSeconds(int.Parse(mode.expires_in));                xml.SelectSingleNode("xml").SelectSingleNode("AccessExpires").InnerText =_accessExpires.ToString();                 xml.Save(filepath);                 Token = mode.access_token;             return Token;   贴上XMLToken.xml 文件  <?xml version="1.0" encoding="utf-8"?> <xml>  <AccessToken>6re6mjuHNHSeptaf8zwxMypCRHWPtTwXOsBffNO2tBPnglPmginrn0N9JwxnlHKw </ AccessToken >  < AccessExpires >2014-05-03 19:04:18</ AccessExpires > </xml> 从上面代码中可以看出首先通过分析XML文档,获取里面的AccessToken及AccessExpires,对比当前时间,如果AccessExpires小于等于当前时间,则重新获取access_token, 代码中的GetAccessToken()就是获取access_token的方法,获取access_token后,将当前时间加上token有效期时间的结果及获取到的access_token重新写入到xml中,至此在以后的有效期范围内,再次获取access_token 将直接读取xml文件中的AccessToken即可。 http://www.wechatstyle.com/weixinkaifa/225.html HTML 4.0 的新特性之一是有能力使 HTML 事件触发浏览器中的动作(action),比如当用户点击某个 HTML 元素时启动一段 JavaScript。下面是一个属性列表,这些属性可插入 HTML 标签来定义事件动作。 当以下情况发生时,出现此事件 onabort 图像加载被中断 onblur 元素失去焦点 onchange 用户改变域的内容 onclick 鼠标点击某个对象 ondblclick 鼠标双击某个对象 onerror 当加载文档或图像时发生某个错误 onfocus 元素获得焦点 onkeydown 某个键盘的键被按下 onkeypress 某个键盘的键被按下或按住 onkeyup 某个键盘的键被松开 onload 某个页面或图像被完成加载 onmousedown 某个鼠标按键被按下 onmousemove 鼠标被移动 onmouseout 鼠标从某元素移开 onmouseover 鼠标被移到某元素之上 onmouseup 某个鼠标按键被松开 onreset 重置按钮被点击 onresize 窗口或框架被调整尺寸 onselect 文本被选定 onsubmit 提交按钮被点击 onunload 用户退出页面 <?xml version="1.0" encoding="utf-8" ?> <log4net> <appender name="TastInfo" type="log4net.Appender.RollingFileAppender"> <file value="Log\\Info\\" /> <appendToFile value="true" /> <rollingStyle value="Composite" /> <maxSizeRollBackups value="-1" /> <maximumFileSize value="1MB" /> <staticLogFileName value="false" /> <DatePattern value="yyyy-MM-dd".txt""/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level - %message%newline" /> </layout> </appender> <appender name="TastError" type="log4net.Appender.RollingFileAppender"> <file value="log\\Error\\" /> <appendToFile value="true" /> <rollingStyle value="Composite" /> <maxSizeRollBackups value="-1" /> <maximumFileSize value="1MB" /> <staticLogFileName value="false" /> <DatePattern value="yyyy-MM-dd".txt""/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level - %message%newline" /> </layout> </appender> <appender name="TastDebug" type="log4net.Appender.RollingFileAppender"> <file value="log\\Debug\\" /> <appendToFile value="true" /> <rollingStyle value="Composite" /> <maxSizeRollBackups value="-1" /> <maximumFileSize value="1MB" /> <staticLogFileName value="false" /> <DatePattern value="yyyy-MM-dd".txt""/> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%date %-5level - %message%newline" /> </layout> </appender> <logger name="Info"> <level value="ALL"/> <appender-ref ref="Info" /> <appender-ref ref="TastInfo" /> </logger> <logger name="Error"> <level value="ALL"/> <appender-ref ref="Error" /> <appender-ref ref="TastError" /> </logger> <logger name="Debug"> <level value="ALL"/> <appender-ref ref="Debug" /> <appender-ref ref="TastDebug" /> </logger> </log4net> log4net的应用错误代码: public class Log private static string DefaultName = "log"; static Log() string path = AppDomain.CurrentDomain.BaseDirectory + @"\log4net_config.xml"; log4net.Config.XmlConfigurator.Configure(new FileInfo(path)); public static log4net.ILog GetLog(string logName) log4net.ILog log = log4net.LogManager.GetLogger(logName); return log; public static void debug(string message) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsDebugEnabled) log.Debug(message); log = null; public static void debug(string message, Exception ex) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsDebugEnabled) log.Debug(message, ex); log = null; public static void error(string message) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsErrorEnabled) log.Error(message); log = null; public static void error(string message, Exception ex) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsErrorEnabled) log.Error(message, ex); log = null; public static void fatal(string message) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsFatalEnabled) log.Fatal(message); log = null; public static void info(string message) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsInfoEnabled) log.Info(message); log = null; public static void warn(string message) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsWarnEnabled) log.Warn(message); log = null; 不输出日志的原因是因为, 默认private static string DefaultName = "log",在配置文件里面找不到对应的节点值。 正确的应用代码: public class Log private const string SError = "Error"; private const string SDebug = "Debug"; private const string DefaultName = "Info"; static Log() var path = AppDomain.CurrentDomain.BaseDirectory + @"\log4net_config.xml"; log4net.Config.XmlConfigurator.Configure(new FileInfo(path)); public static log4net.ILog GetLog(string logName) var log = log4net.LogManager.GetLogger(logName); return log; public static void Debug(string message) var log = log4net.LogManager.GetLogger(SDebug); if (log.IsDebugEnabled) log.Debug(message); public static void Debug(string message, Exception ex) var log = log4net.LogManager.GetLogger(SDebug); if (log.IsDebugEnabled) log.Debug(message, ex); public static void Error(string message) var log = log4net.LogManager.GetLogger(SError); if (log.IsErrorEnabled) log.Error(message); public static void Error(string message, Exception ex) var log = log4net.LogManager.GetLogger(SError); if (log.IsErrorEnabled) log.Error(message, ex); public static void Fatal(string message) var log = log4net.LogManager.GetLogger(DefaultName); if (log.IsFatalEnabled) log.Fatal(message); public static void Info(string message) log4net.ILog log = log4net.LogManager.GetLogger(DefaultName); if (log.IsInfoEnabled) log.Info(message); public static void Warn(string message) var log = log4net.LogManager.GetLogger(DefaultName); if (log.IsWarnEnabled) log.Warn(message); 总结:log4net.LogManager.GetLogger(Name),这里面的Name要在配置文件中,有对应的节点值。

Linux下锁定账号,禁止登录系统的设置总结

在我们运维工作中,会经常要求一些用户不允许登陆系统,以加固系统安全。今天这里介绍下锁定账号登陆的几种方法: 一、最常用方式,修改用户的shell类型为/sbin/nologin  (推荐使用)这种方式会更加人性化一点,因为不仅可以禁止用户登录,还可以在禁用登陆时给提示告诉它这么做的原因。修改/etc/nologin.txt,没有的话就手动新建一个,在里面添加给被禁止用户的提示(这种方式的所有用户的锁定信息都在这个文件中,在登陆时给与提示)。 如下,禁用wangshibo账号登陆系统: [root@host-192-168-1-117 ~]# useradd wangshibo [root@host-192-168-1-117 ~]# echo "123456"|passwd --stdin wangshibo Changing password for user wangshibo. passwd: all authentication tokens updated successfully. [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/bin/bash [root@host-192-168-1-117 ~]# sed -i 's#/home/wangshibo:/bin/bash#/home/wangshibo:/sbin/nologin#g' /etc/passwd [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/sbin/nologin [root@host-192-168-1-117 ~]# touch /etc/nologin.txt [root@host-192-168-1-117 ~]# cat /etc/nologin.txtIn order to protect the system security, this type of user is locked! 现在尝试用wangshibo账号登陆系统,就会被拒绝,并给出提示信息: [ops@host-192-168-1-117 ~]$ su - wangshibo Password: In order to protect the system security, this type of user is locked! [ops@host-192-168-1-117 ~]$ 解禁用户登陆就是把shell改为它原有的就可以了 [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/sbin/nologin [root@host-192-168-1-117 ~]# sed -i 's#/home/wangshibo:/sbin/nologin#/home/wangshibo:/bin/bash#g' /etc/passwd [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/bin/bash [root@host-192-168-1-117 ~]# su - ops [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  [wangshibo@host-192-168-1-117 ~]$ ---------------------------------------------------------------------------------------可以使用usermod命令修改用户的shell类型,加-s参数,如 [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/bin/bash [root@host-192-168-1-117 ~]# usermod wangshibo -s /sbin/nologin  [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/sbin/nologin 另外注意下一个小细节:这一种方法,无论是从root用户,还是从其他用户,都不能ssh登陆或su切换到锁定账号下--------------------------------------------------------------------------------------- 二、修改用户配置文件/etc/shadow,将第二栏设置为“*”使用这种方式会导致该用户的密码丢失,要再次使用时,需重设密码。一般不推荐这种方式! [root@host-192-168-1-117 ~]# cat /etc/passwd|grep wangshibo wangshibo:x:500:500::/home/wangshibo:/bin/bash [root@host-192-168-1-117 ~]# cat /etc/shadow|grep wangshibo wangshibo:$1$0/5NU4y2$OBGISa8yaloVNYVLFCoP3.:17133:::::: [root@host-192-168-1-117 ~]# cat /etc/shadow|grep wangshibo                  # 将第二栏密码设置为* wangshibo:*:17133:::::: [root@host-192-168-1-117 ~]# su - ops [ops@host-192-168-1-117 ~]$ su - wangshibo                 #不能登陆系统  Password:  su: incorrect password 解禁用户登陆,需要重置密码 [root@host-192-168-1-117 ~]# echo "123456"|passwd --stdin wangshibo Changing password for user wangshibo. passwd: all authentication tokens updated successfully. [root@host-192-168-1-117 ~]# cat /etc/shadow|grep wangshibo wangshibo:$1$RPfkekf7$QAUGmJ0SCIb64aEvJvNif1:17133:::::: [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  [wangshibo@host-192-168-1-117 ~]$ 三、使用命令passwdpasswd -l 用户          //锁定账号,-l:lockpasswd -u 用户        //解禁用户,-u:unlock [root@host-192-168-1-117 ~]# passwd -l wangshibo Locking password for user wangshibo. passwd: Success [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  su: incorrect password [root@host-192-168-1-117 ~]# passwd -u wangshibo Unlocking password for user wangshibo. passwd: Success [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  [wangshibo@host-192-168-1-117 ~]$ 四、使用命令usermodusermod -L 用户         //锁定帐号,-L:lockusermod -U 用户        //解锁帐号,-U:unlock [root@host-192-168-1-117 ~]# usermod -L wangshibo [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  su: incorrect password [root@host-192-168-1-117 ~]# usermod -U wangshibo [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  [wangshibo@host-192-168-1-117 ~]$ --------------------------------------------------------------------------------------- 这里有个细节需要注意一下:第三和第四种方式,即passwd或usermod命令锁定的用户:1)无论从root用户还是其他普通用户,都不能ssh登陆锁定用户下2)可以从root用户su切换到锁定用户下,但是用其他普通用户不能su切换到锁定用户下--------------------------------------------------------------------------------------- 五、禁止所有的用户登录(手动创建/etc/nologin文件)如果不想让除root用户之外的其他所有用户登录系统(比如在系统维护情况下),如果按照上面的几种方式,就需要一个一个地去禁止用户登录,这就是一种很傻X的工作方式,效率也很低! 下面介绍一种简洁有效的设置方式:只需要在/etc目录下建立一个nologin文档,那么Linux上的所有用户(除了root以外)都无法登录!! [root@host-192-168-1-117 ~]# touch /etc/nologin 在/etc/nologin(注意:这可不是第一种方式中的nologin.txt)文件里面可以自定义一些内容,告诉用户为何无法登录。 [root@host-192-168-1-117 ~]# cat /etc/nologin 抱歉,系统维护中,暂时禁止登陆! 这样,就会发现除root之外的其他用户统统无法登陆系统了。 [root@linux-node2 ~]# ssh root@192.168.1.117 抱歉,系统维护中,暂时禁止登陆! [root@host-192-168-1-117 ~]# [root@linux-node2 ~]# ssh wangshibo@192.168.1.117 wangshibo@192.168.1.117's password:  抱歉,系统维护中,暂时禁止登陆! Connection closed by 192.168.1.117 [root@linux-node2 ~]# ssh ops@192.168.1.117 ops@192.168.1.117's password:  抱歉,系统维护中,暂时禁止登陆! Connection closed by 192.168.1.117 注意一点:这种方法设置后,只是禁止了从外部ssh登陆本机时有效!但是在本机上,无论是从root用户还是其他普通用户使用su命令切换到锁定用户下都不受影响。 [root@host-192-168-1-117 ~]# su - ops [ops@host-192-168-1-117 ~]$ su - wangshibo Password:  [wangshibo@host-192-168-1-117 ~]$ 解禁帐号也简单,直接将/etc/nologin删除就行了! [root@host-192-168-1-117 ~]# rm -f /etc/nologin [root@host-192-168-1-117 ~]# ll /etc/nologin ls: cannot access /etc/nologin: No such file or directory [root@linux-node2 ~]# ssh wangshibo@192.168.1.117 wangshibo@192.168.1.117's password:  [wangshibo@host-192-168-1-117 ~]$ ***************当你发现自己的才华撑不起野心时,就请安静下来学习吧*************** 分类: 常规运维实录,性能调试及安全防范 本文转自散尽浮华博客园博客,原文链接:http://www.cnblogs.com/kevingrace/p/6109818.html,如需转载请自行联系原作者

可以看到extents在逻辑上是链表形式,以及每个extent的数据量、以及所在data file的offset位置. 从上面介绍中已经得知,删除document会导致磁盘碎片,有些update也会导致磁盘碎片,比如update导致文档尺寸变大,进而超过原来分配的空间;当有新的insert操作时, mongodb会检测现有的extents中是否合适的碎片空间可以被重用,如果有,则重用这些fragment,否则分配新的存储空间。磁盘碎片,对write操作有一定的性能影响,而且 会导致磁盘空间浪费;如果你需要删除某个collection中大部分数据,则可以考虑将有效数据先转存到新的collection,然后直接drop()原有的collection。或者使用 db.runCommand({compact: '<collection>'})。 如果你的database已经运行一段时间,数据已经有很大的磁盘碎片(storageSize与dataSize比较),可以通过mongodump将指定database的所有数据导出,然后将原有的db删除, 再通过mongorestore指令将数据重新导入。(同compact,这种操作需要停机维护) mongod中还有2个默认的database,系统级的,"admin"和"local";它们的存储原理同上,其中"admin"用于存储"用户授权信息",比如每个database中用户的role、权限等; "local"即为本地数据库,我们常说的oplog(replication架构中使用,类似与binlog)即保存在此数据库中。 2)Namespace文件 对于namespace文件,比如"test.ns"文件,默认大小为16M,此文件中主要用于保存"collection"、index的命名信息,比如collection的"属性"信息、每个索引的属性类型等, 如果你的database中需要存储大量的collection(比如每一小时生成一个collection,在数据分析应用中),那么我们可以通过配置文件"nsSize"选项来指定。 3)journal文件 journal日志为mongodb提供了数据保障能力,它本质上与mysql binlog没有太大区别,用于当mongodb异常crash后,重启时进行数据恢复;这归结于mongodb的数据持久写入 磁盘是滞后的。默认情况下,"journal"特性是开启的,特别在production环境中,我们没有理由来关闭它。(除非,数据丢失对应用而言,是无关紧要的) 一个mongodb实例中所有的databases共享journal文件。 对于write操作而言,首先写入journal日志,然后将数据在内存中修改(mmap),此后后台线程间歇性的将内存中变更的数据flush到底层的data files中,时间间隔为60秒; write操作在journal文件中是有序的,为了提升性能,write将会首先写入journal日志的内存buffer中,当buffer数据达到100M或者每隔100毫秒,buffer中的数据将会flush 到磁盘中的journal文件中;如果mongodb异常退出,将可能导致最多100M数据或者最近100ms内的数据丢失,flush磁盘的时间间隔有配置项"commitIntervalMs"决定,默认为 100毫秒。mongodb之所以不能对每个write都将journal同步磁盘,这也是对性能的考虑,mysql的binlog也采用了类似的权衡方式。开启journal日志功能,将会导致write性能 有所降低,可能降低5~30%,因为它直接加剧了磁盘的写入负载,我们可以将journal日志单独放置在其他磁盘驱动器中来提高写入并发能力(与data files分别使用不同的 磁盘驱动器)。 如果希望数据尽可能的不丢失,可以考虑: 1)减小commitIntervalMs的值 2)每个write指定"write concern"中指定"j"参数为true  3)最佳手段就是采用"replica set"架构模式,通过数据备份方式解决,同时还需要在"write concern"中指定"w"选项,且保障级别不低于"majority"。 最终需要在"写入性能"和"数据一致性"两个方面权衡,即CAP理论。 根据write并发量,journal日志文件为1G,如果指定了smallFiles配置项,则最大为128M,和data files一样journal文件也采用了"preallocated"方式,journal日志保存在 dbpath下"journal"子目录中,一般会有三个journal文件,每个journal文件格式类似于"j._<序列数字>"。并不是每次buffer flush都生成一个新的journal日志,而是当前 journal文件即将满时会预创建一个新的文件,journal文件中保存了write操作的记录,每条记录中包含write操作内容之外,还包含一个"lsn"(last sequence number), 表示此记录的ID;此外我们会发现在journal目录下,还有一个"lsn"文件,这个文件非常小,只保存了一个数字,当write变更的数据被flush到磁盘中的data files后,也 意味着这些数据已经持久化了,那么它们在"异常恢复"时也不需要了,那么其对应的journal日志将可以删除,"lsn"文件中记录的就是write持久化的最后一个journal记录的ID, 此ID之前的write操作已经被持久写入data files,此ID之前的journal在"异常恢复"时则不需要关注;如果某个journal文件中最大 ID小于"lsn",则此journal可以被删除或者重用。 var pi_value=Math.PI; var sqrt_value=Math.sqrt(15); 注释:Math 对象并不像 Date 和 String 那样是对象的类,因此没有构造函数 Math(),像 Math.sin() 这样的函数只是函数,不是某个对象的方法。您无需创建它,通过把 Math 作为对象使用就可以调用其所有属性和方法。 1. Math 对象属性返回顶部 Math 对象属性 返回算术常量 e,即自然对数的底数(约等于2.718)。 返回 2 的自然对数(约等于0.693)。 返回 10 的自然对数(约等于2.302)。 LOG2E 返回以 2 为底的 e 的对数(约等于 1.414)。 LOG10E 返回以 10 为底的 e 的对数(约等于0.434)。 返回圆周率(约等于3.14159)。 SQRT1_2 返回返回 2 的平方根的倒数(约等于 0.707)。 SQRT2 返回 2 的平方根(约等于 1.414)。

echarts在.Net中使用实例(一) 简单的Demo

这个必须要有前言,即便很短,对于有强迫症的人来说不容易啊。言归正传,之前做图一直使用rdlc自带的格式,虽然任务完成,但是一直觉得不太美观, 空余时间开始找其他的插件,终于找到了Highchart和echarts,这一系列主要是针对echarts. 关于Echarts 百度比我更清楚,我就不说了! echarts的实例参考地址:http://echarts.baidu.com/doc/example.html echarts的文档参考地址:http://echarts.baidu.com/doc/doc.html echarts(版本2.2.7)下载地址:http://echarts.baidu.com/build/echarts-2.2.7.zip 在项目中新建echarts文件夹,并将下载的echarts-2.2.7.zip解压,将build下的dist文件夹中所有的文件拷贝到echarts文件夹中,如下图 根据文档只需要几分钟的功夫,代码如下:  View Code 效果如下图,效果是不是很棒 使用ajax动态加载数据,请看下回分解。 本文转自左正博客园博客,原文链接:http://www.cnblogs.com/soundcode/p/6253518.html,如需转载请自行联系原作者

ylbtech-Unitity: cs-Filters HealthcareAuthorizeAttribute.cs HealthcareHandleErrorAttribute.cs HealthcareJSONHandleErrorAttribute.cs 1.A,效果图返回顶部 1.B,源代码返回顶部 1.B.1,HealthcareAuthorizeAttribute.cs  View Code 1.B.2,HealthcareHandleErrorAttribute.cs  View Code 1.B.3,HealthcareJSONHandleErrorAttribute.cs  View Code 1.B.4, 1.C,下载地址返回顶部 本文转自ylbtech博客园博客,原文链接:http://www.cnblogs.com/ylbtech/p/4079513.html,如需转载请自行联系原作者