在iOS开发中,遇到耗时操作,我们常用到大半线程技术。Grand Central
Dispatch
(GCD)是Apple开发的一个差不多对编程的缓解措施,只待定义想如果实行的职责,然后上加至适当的调度班(dispatch
queue)。GCD会负责创建线程和调度你的职责,系统一直提供线程管理。

微软全球可总裁Soma,负责微软店Developer
Division的工作,在博客及发布了稿子Windows Server
AppFabric:更好,更快,更便宜。微软服务器和Internet信息服务(IIS)没有提供用于部署、管理暨监控特定项目Web应用程序的一体的劳务,Windows服务器AppFabric的出是为了响应大量团组织以及开发商的渴求,多年来她们径直期待微软资“应用程序服务器”。微软服务器AppFabirc基本填补了此空白,它看作微软服务器自由扩展以及预测Windows服务器将发行的地方组件的可用性。

一、队列:

Windows Server AppFabric作为Windows
Server的扩展,应用程序可以部分或者任何的免费使用。它提供了一样名目繁多功能来增进性,并增强Web和混合使用之管制。Windows
Server
AppFabric使用我们所耳熟能详的.NET技术,提供了分布式缓存技术,以及分布式管理暨监控的基本功结构。

基本概念:

1.GCD底一个重点概念是行,它的核心理念:将长期运行的天职拆分成多只干活单元,并以这些单元添加到dispath
queue中,系统会为咱管理这些dispath
queue,为我们在多单线程上推行工作单元,我们无欲直接开行与管制后台线程。

2.系提供了好多预定义的dispath
queue,包括可以保证始终在主线程上实行工作的dispath
queue。也堪创造自己之dispath queue,而且得创造任意多独。GCD的dispath
queue严格遵循FIFO(先进先出)原则,添加到dispath
queue的做事单元将老以进入dispath queue的依次启动。

3.dispatch queue按先进先出的顺序,串行或连发地执行任务

1> serial dispatch queue一糟糕只能实行一个任务,
当前任务完成才起来出列并启动下一个职责

2> concurrent dispatch queue则尽量多地开行任务并发执行

精益求精用户操作经验和系统可扩展性的平等种办法是加速他们本着信息的拜会。如果多个服务器上基本上个应用程序访问同一个数据库时,对数码的访则变成瓶颈。如果asp.net页面等待看数据库,增加又多之前端服务器是吃事无补的。现在欲平等栽扩大的方法:如何用反复造访的数据分布到差不多华服务器上一直给该访问,从而缓解访问同大数据库服务器的瓶颈。一个得力的主意就是树立一个揭示缓存服务(distributed
cache),这个服务向多光客户端机器分发。相对于从一个单身的数据库获取数据,现在asp.net页面可以从多独不同的机器及获取数据了,负载均衡,应用程序会生双重好的表现。这就是AppFabric
Caching Services要召开的。

dispatch queue分成以下三种:

1)运行于主线程的Main queue,通过dispatch_get_main_queue获取。

2)并行队列global dispatch
queue,通过dispatch_get_global_queue获得,由网创造三单不等优先级的dispatch
queue。并行队列的实施各个及该进入队列的各个相同。

3)串行队列serial
queues一般用来按梯次并看,可创造任意数量的串行队列,各个串行队列中是出新的。

当思使任务仍有一个一定的依次执行时,串行队列是格外有因此底。串行队列在与一个时光仅实行一个任务。我们可用串行队列代替锁去保护共享的数额。和沿不同,一个串行队列可以保任务在一个而预知的逐条下实施。

serial
queues通过dispatch_queue_create创建,可以使用函数dispatch_retain和dispatch_release去多或缩减引用计数。

 

AppFabric Caching Services的一个最主要组件是缓存客户端(cache
client),如asp.net页面,它访问缓存群集,缓存群集由多大运行缓存服务之服务器组成,每台服务器都运行一个AppFabric
Caching
Services的实例,且每个缓存服务还蕴涵部分多少缓存。缓存客户端可分包自己之本土缓存,通过软件方式作为AppFabric
Caching Services的同组成部分对外提供劳动。

二、GCD的用法:

//  后台执行:
 dispatch_async(dispatch_get_global_queue(0, 0), ^{
      // something
 });

 // 主线程执行:
 dispatch_async(dispatch_get_main_queue(), ^{
      // something
 });

 // 一次性执行:
 static dispatch_once_t onceToken;
 dispatch_once(&onceToken, ^{
     // code to be executed once
 });

 // 延迟2秒执行:
 double delayInSeconds = 2.0;
 dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
 dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
     // code to be executed on the main queue after delay
 });

 // 自定义dispatch_queue_t
 dispatch_queue_t urls_queue = dispatch_queue_create("blog.devtang.com", NULL);
 dispatch_async(urls_queue, ^{  
   // your code 
 });
 dispatch_release(urls_queue);

 // 合并汇总结果
 dispatch_group_t group = dispatch_group_create();
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程一
 });
 dispatch_group_async(group, dispatch_get_global_queue(0,0), ^{
      // 并行执行的线程二
 });
 dispatch_group_notify(group, dispatch_get_global_queue(0,0), ^{
      // 汇总结果
 });

当缓存客户端第一坏利用数据,这些数据可是asp.net应用程序的使用者提供的音信,也得以是数据库读取的价,可以通过AppFabric
Caching
Services客户端库明确的向缓存群集使用唯一的名来储存这些多少。(后面也会证明,asp.net应用程序也可以同session对象透明的来开这一体,因此利用缓存服务并不需要对代码做其他变动)对于客户端的话,缓存群集中的富有缓存服务器显示也一个逻辑的缓存服务,客户端无需了解呢非需关注具体是哪一个服务器也其提供数据,如果选了地方缓存,客户端也堪于那地面缓存中存储数据项。

其三、一个以GCD的例子:

今一个耗时操作,从 start working
开始工作,采用多线程,然后将结果显示出来。

声明控件:

@property (weak, nonatomic) IBOutlet UIButton *startButton;
@property (weak, nonatomic) IBOutlet UITextView *resultsTextView;
@property (weak, nonatomic) IBOutlet UIActivityIndicatorView *spinner;

点击startButton,开始履行。

- (IBAction)doWork:(id)sender
{

    NSDate *startTime = [NSDate date];

    self.startButton.enabled = NO;

    [self.spinner startAnimating];

    //dispatch_get_global_queue(),抓取一个已经存在并始终可用的全局队列,该函数接受两个参数:第一个指定优先级;第二个目前未使用,应该始终为0.
    dispatch_queue_t queue =
        dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    //将该队列以及它后面的代码块 一起传递给dispatch_async()函数,GCD然后获取整个程序块,并将它传递给一个后台线程,程序块将在这里一次执行一步。
    dispatch_async(queue, ^{
        NSString *fetchedData = [self fetchSomethingFromServer];
        NSString *processedData = [self processData:fetchedData];
        __block NSString *firstResult;
        __block NSString *secondResult;

        dispatch_group_t group = dispatch_group_create();
        //dispatch_group_async()函数异步分派的所有程序块的设置为松散的,以尽可能快地执行。
        dispatch_group_async(group, queue, ^{
            firstResult = [self calculateFirstResult:processedData];
        });
        dispatch_group_async(group, queue, ^{
            secondResult = [self calculateSecondResult:processedData];
        });

        dispatch_group_notify(group, queue, ^{
            NSString *resultsSummary = [NSString stringWithFormat:
                                        @"First: [%@]\nSecond: [%@]", firstResult,
                                        secondResult];

            //dispatch_get_main_queue函数返回的队列,该函数总是提供线程上的特定队列,并执行需要使用主线程的程序块
            dispatch_async(dispatch_get_main_queue(), ^{
                self.resultsTextView.text = resultsSummary;
                self.startButton.enabled = YES;
                [self.spinner stopAnimating];

            });

            NSDate *endTime = [NSDate date];
            NSLog(@"Completed in %f seconds",
                  [endTime timeIntervalSinceDate:startTime]);
        });
    });
}

另措施:

//模拟从服务器获取数据
- (NSString *)fetchSomethingFromServer
{
    [NSThread sleepForTimeInterval:1];
    return @"Hi there";
}

- (NSString *)processData:(NSString *)data
{
    [NSThread sleepForTimeInterval:2];
    return [data uppercaseString];
}

- (NSString *)calculateFirstResult:(NSString *)data
{
    [NSThread sleepForTimeInterval:3];
    return [NSString stringWithFormat:@"Number of chars: %lu",
            (unsigned long)[data length]];
}

- (NSString *)calculateSecondResult:(NSString *)data
{
    [NSThread sleepForTimeInterval:4];
    return [data stringByReplacingOccurrencesOfString:@"E"
                                           withString:@"e"];
}

结果显示:

统计 1

当客户端需要重走访同的数目项时,需要运用数据项之讳。查询首先从地面缓存中寻找(如果安了本地缓存)。如果数额项能够找到,则直回缓存数据,如果数量尚未以本地缓存,查询将让送至缓存群集,如果数据可知以缓存群集中找到,则打缓存群集返回数据。数据为客户端传送的进程,就是客户端提出数据请求,AppFabric
Caching
Services为该准备并赶回结果。如果数额没有当本地与缓存群集找到,客户端需要打其它地方查询信息,如数据库。

季、GCD的旁一个用场是好吃程序于后台比长期之周转。

当未曾下GCD时,当app被依home键退出后,app仅发生尽多5秒钟的时光做片封存还是理清资源的干活。但是以利用GCD后,app最多发生10分钟的工夫以后台长久运行。这个时间得为此来做清理地面缓存,发送统计数据等工作。

受程序在后台长久运行的以身作则代码如下:

// AppDelegate.h文件
@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundUpdateTask;

// AppDelegate.m文件
- (void)applicationDidEnterBackground:(UIApplication *)application
{
    [self beingBackgroundUpdateTask];
    // 在这里加上你需要长久运行的代码
    [self endBackgroundUpdateTask];
}

- (void)beingBackgroundUpdateTask
{
    self.backgroundUpdateTask = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{
        [self endBackgroundUpdateTask];
    }];
}

- (void)endBackgroundUpdateTask
{
    [[UIApplication sharedApplication] endBackgroundTask: self.backgroundUpdateTask];
    self.backgroundUpdateTask = UIBackgroundTaskInvalid;
}

 

AppFabric Caching
Services被规划由.net应用程序使用,因此,缓存数据项好是任何可以序列化的.net对象。一旦目标上缓存,应用程序可以创新缓存的本子要显示的勾其;缓存数据也足以叫缓存服务活动去,删除条件可是设定的超时时或为再次累造访的多寡代表,缓存到当地的数据项同样如此,同时,本地缓存可以装为和缓存群集的转移机关同步。

差不多个缓存客户端可共享相同的休息存群集,这是有含义之,因为一个只是伸缩扩展的应用程序可以跨多个服务器复制它的事情逻辑(如asp.net页面),并走访缓存。同时,安全与否是一个亟待提出的题目,为了使共享的高风险降到比逊色,缓存客户端或缓存服务器之间传递的数目要数字签名和加密,管理员会范围账户对每个缓存的走访权限。尽管如此,组织还待保证使用及一个缓存的多个客户端是不过信任的,因为他们默认可以相互拜访相互之间的数目。

缓存是本着形形色色的数据经常老管用的。例如,对于接近于在线销售的产品目录信息等生成于缓或者核心没生成的数目,缓存有良好之心得,它可在以满足多只客户端的求;缓存的另外一个应用是储存变化之数据,但以只能有一个客户端访问,如asp.net的session对象。再次强调一下,不要来对缓存的产出访问控制问题。

然,对于急需转移又要而受多单客户端访问的数量应怎么惩罚吧?缓存服务还是可下,但状态会复杂一下,并作控制是必的。为了解决这个题材,AppFabric
Caching
Services提供了少数种并作控制方式:一栽是开展的面世控制方法,即为每个缓存对象提供版本号;另一样栽是不容乐观的起控制方法,即利用显式锁。

应用程序一般是经服务之不二法门暴露功能,对于Windows应用程序来说,这些劳务多状下是通过WCF实现之,同时,一些服务的逻辑通过工作流来实现会晤重新好,因此,在工作流基础及创立WCF服务为会发良怪之也许。我们怎样被这些劳务运行起来吧?windows提供了成千上万通用的host宿主方式,开发者可以按该所急需创建host程序。但创造一个高效的、可管理之host宿主却不是便于之工作了。使用wcf与wf,通过Windows
server自身提供的作用方便之实现对host的支持和管制,这虽是AppFabric
Hosting Services所要开的工作。

WCF提供常用暴露及运用服务的路,WF提供创建工作流逻辑的支撑。AppFabric既管理WCF服务,也管理工作流服务(工作流服务也是均等种植WCF服务)。其区别在于服务遭遇含的情节。WCF服务的情就是是公的代码。而对于工作流服务,你习以为常需要利用Visual
Studio工作流设计器绘制而的工作流以及同组可选用的工作流活动。工作流活动着要蕴涵部分动,使你的工作流成为一个服务,并能调用其它的劳务。

俺们为可用工作流活动理解也一个零件。你可以从已经有些组件中创造新的动,即集成移动。用不同之零件合成应用程序,这是一个深强的型,不论对云端应用或今天底寻常应用程序都为要命管用。

Visual Studio
WCF工作流服务用模板帮助您以缺乏日内开行运行而的工作流服务,并能够于AppFabric中查看结果。欲启动服务,你得下模板创建一个初的类型,并安装项目受到的Web属性,使该采用当地的IIS服务器。构建而的品种并运行,内建的WCF测试客户端就见面运作。你得经过该测试客户端向你的工作流发送数据并查阅结果。以代码为底蕴之WCF服务也起近似的模版,因此若可以立即以你的关注点放在用代码编写的工作逻辑上,而未用修WCF基础结构或任何相关的宿主逻辑与管理功能——AppFabric替你成就了这些工作。

AppFabric操作板可以叫你当IIS管理器中翻所有与您的代码和工作流服务相关的统计数据。工作流实例历史数据有见了都激活和成就的工作流。操作板还可以帮忙而监视以及操纵工作流的持久性。所有的劳动调用都见面于盯梢。创建而自己的监察事件并将其出示在操作板中也非常简单。

AppFabric从一个衔接一个之位移受到跟踪工作流的施行,并将信息在操作板中呈现出来。这对于故障分析及明有工作流实例的流运行情况来说十分有因此。你居然可以从你的工作流中于AppFabric暴露而的数目,并通过查询其数量找到她所含有的办事流实例。

还详细信息参见
http://www.microsoft.com/windowsserver2008/en/us/default.aspx