APM(=Asynchronous Programming Model(=异步编程模型))
.NET为我们提供了很多异步编程的方案,而在即将随.NET 4.0正式发布的F#更是为开发人员提供了强大的并行编程能力(http://www.infoq.com/cn/news/2009/11/pdc09-fsharp,http://msdn.microsoft.com/zh-cn/magazine/cc967279.aspx)。
CLR下的几种异步编程模型介绍
使用基于组件的方式进行异步编程:
ms为我们提供了一个现成的BackgroundWorker,它能够满足一般的异步编程需求,提供了很多事件(比如:ProgressChanged(在进度变更时),RunWorkerCompleted(当异步调用的方法完成之后)),配置好其属性和委托后调用DoWorkAsync即可开始异步过程。
使用经典的BeginXXX和EndXXX异步委托。
在.NET中,任何一个委托都能够使用BeginInvoke来使委托方法以异步的方式被调用。BeginInvoke会返回一个IAsyncResult对象,通过它能够获取异步过程的信息(比如是否已经完成,获得WaitHandle),可以使用AsyncCallback设定异步完成时的事件,也可以通过IAsyncResult.AsyncWaitHandle来等待异步过程,或是通过EndInvoke来等待过程结束。资料不少,这里不再复述。
园子里的参考:http://www.cnblogs.com/AndyHuang/archive/2008/12/24/1361267.html
我们也自制一个简易的提供异步过程调用组件。
下面罗列出其基本功能要求
能够方便的生成异步线程(下面称其为TaskHostThread),每个线程拥有一个可排序的任务队列,每个线程会按照任务的优先级去串行的执行他们。 |
TaskHostThread是可控的,即可以获取其运行状态并安全的被终止它。 |
TaskHostThread具有可复用性,在任务队列为空时进入等待状态,在新的任务加入后能立即激活。 |
能随时获得每个任务的状态(比如是否正在执行,是否处于暂停状态,是否已经被废弃)。 |
能够方便的、有选择性的将几个任务放在一个线程中去串行执行。 |
能够控制同一个线程中调用任务的优先级别,高级别的任务即使是之后加入的也能够提前得到运行的机会。 |
设计说明
IAsyncServiceDispatcher:用户能够使用IAsyncServiceDispatcher来注册任务到异步线程中,同时它还提供对线程 和 任务的细粒度控制(比如暂停,废弃,执行等)。
IHostThreadTable:这是一个存放每个ITaskHostThread实例的容器,IAsyncServiceDispatcher可以通过它来创建线程对象并对其进行检索等操作。
ITaskHostThread:负责线程创建、控制以及任务队列的处理。
ITaskHostThreadProvider:一个类型提供器,默认使用TaskHostThread这个实现类。
ITaskWrapper,ITask。ITask仅封装执行的代码,ITaskWrapper包装ITask,额外提供了诸如任务优先级、任务名称等属性。
TaskState:枚举,用于指示线程/任务所处的状态。
如果需要将一个任务放到某一个线程中去异步执行可以使用类似如下的方法:void RegisterTask(string taskHostIdentity, ITaskWrapper task, ITaskPrincipal principal);taskHostIdentity表示任务分派到的那个线程的标识,ITaskWrapper 提供任务要执行的代码,ITaskPrincipal能够干预任务的执行行为。
其他:关于线程的挂起,使用类似while(……){Thread.Sleep(……)}这种轮回等待的方式是很耗费资源的,这里使用了
AutoResetEvent。
接口定义
public interface IAsyncServiceDispatcher //对任务进行控制(只有实现ITaskWrapper才可以) //对线程进行控制 public interface IHostThreadTable public interface ITask public interface ITaskHostThread public interface ITaskHostThreadProvider /// <summary> |
具体实现
namespace Sopaco.Lib.ServiceModel.AsyncServiceDispatcher #region Constructors & Initializer #region IAsyncServiceDispatcher 成员 public IHostThreadTable Table public void RegisterTask(ITaskWrapper task) public void RegisterTask(string taskHostIdentity, ITaskWrapper task) public void RegisterTask(string taskHostIdentity, ITaskWrapper task, ITaskPrincipal principal) public ITaskHostThreadProvider NewHostThreadProvider #region IAsyncServiceDispatcher 成员 public void PauseTask(string hostThreadIdentity, string taskIdentity) public void TerminateTask(string hostThreadIdentity, string taskIdentity) public void ResumeTask(string hostThreadIdentity, string taskIdentity) public void PauseThreadHost(string hostThreadIdentity) public void TerminateThreadHost(string hostThreadIdentity) public void ResumeThreadHost(string hostThreadIdentity) public void TryTerminateAllThreadHost() namespace Sopaco.Lib.ServiceModel.AsyncServiceDispatcher #region Constructors & Initializer } #region IHostThreadTable 成员 public bool QueryExist(string name) public IEnumerable<string> Keys public ITaskHostThread this[string name] #region private Helper Methods namespace Sopaco.Lib.ServiceModel.AsyncServiceDispatcher #region Constructors & Initializer } public TaskState ExpectedState public void TryExitThread() public void StartCurrent() public void PauseCurrentAndNext() public void PauseCurrent() public void ResumeCurrent() public void TerminateCurrentAndNext() public void TerminateCurrent() public void TerminateAll() public void AddTask(ITaskWrapper task) public void AddTaskAndRefresh(ITaskWrapper task) public void RemoveTask(string identity) public void PauseTask(string identity) public IList<ITaskWrapper> PausingTask #endregion #region private Helper Methods public class TaskHostThreadProvider : ITaskHostThreadProvider public ITaskHostThread CreateTaskHostThread() #endregion public enum TaskResult public enum TaskState public class TaskWrapperBase : ITaskWrapper #region Constructors & Initializer } #region ITaskWrapper 成员 public ITask InnerTask public TaskState State public TaskState ExpectedState public int Priority public string Identify #endregion #region ITask 成员 public TaskResult Call() #endregion |
project放到sky driver上了:http://public.blu.livefilestore.com/y1ppmpl1LORAqLOBcxdTkZhcnwLaSsBb_zxte5DdifEL8v85lIWMnPJpmS6sK5Ait7gEV4zb9u77JACyVfMqNu9Pg/AsyncServiceDispatcher.rar?download