与非CCR代码互操作
导读:CCR可以轻松的承载STA组件或者与它互操作:组件应该创建一个只有一个线程的CCR Dispatcher实例,并且在Dispatcher的构造函数中指定线程套间策略。DispatcherQueue实例就可以在与需要和遗留代码交互 的地方使用这个dispatcher来激活处理函数(activating handlers)。这些处理函数就可以安全的访问COM或者WinForm对象,同时对其他的CCR组件隐藏它们的STA关系,以便其他CCR组件可以 简单的投递元素到常规的CCR ports而不需要关心port上的处理函数使用的是什么dispatcher。
原文链接
线程套间约束
当与某些遗留的Windows组件,特别是COM对象交互时需要特定的线程套件策略。甚至最近的框架,例如.net WinForms,也需要在运行WinForm的线程上应用单线程套间(SingleThreadedApartment)策略。
CCR可以轻松的承载STA组件或者与它互操作:组件应该创建一个只有一个线程的CCR Dispatcher实例,并且在Dispatcher的构造函数中指定线程套间策略。DispatcherQueue实例就可以在与需要和遗留代码交 互的地方使用这个dispatcher来激活处理函数(activating handlers)。这些处理函数就可以安全的访问COM或者WinForm对象,同时对其他的CCR组件隐藏它们的STA关系,以便其他CCR组件可以 简单的投递元素到常规的CCR ports而不需要关心port上的处理函数使用的是什么dispatcher。
CCR WinFrom适配库(Ccr.Adapters.Winforms.dll)是一个在CCR中运行.net WinForm的便利方法。
与应用的主线程协调
CCR软件组件经常在一个CLR应用的上下文中中执行,例如一个独立执行程序。.net运行时使用一个操作系统 线程启动一个程序,当线程退出时终止程序。由于CCR应用是异步、并发的,所以它们在没有消息被发送时处于非激活状态,并且几乎不会阻塞任何线程。CCR Dispatcher将保持线程在一种高效的休眠状态,但是如果其它的线程被作为后台线程创建,应用程序将会退出,那么CCR还在执行。
一个与CLR启动的同步世界接口的常见模式是使用System.Threading.AutoResetEvent来阻塞应用的主线程,直到CCR应用完成。AutoResetEvent事件可以被任何CCR处理函数触发。
例25.
void InteropBlockingExample()
{
// create OS event used for signalling
AutoResetEvent signal = new AutoResetEvent(false);
// schedule a CCR task that will execute in parallel with the rest of
// this method
Arbiter.Activate(
_taskQueue,
new Task<AutoResetEvent>(signal, SomeTask)
);
// block main application thread form exiting
signal.WaitOne();
}
void ThrottlingExample()
{
int maximumDepth = ;
Dispatcher dispatcher = new Dispatcher(, "throttling example");
DispatcherQueue depthThrottledQueue = new DispatcherQueue("ConstrainQueueDepthDiscard",
dispatcher,
TaskExecutionPolicy.ConstrainQueueDepthDiscardTasks,
maximumDepth);
Port<int> intPort = new Port<int>();
Arbiter.Activate(depthThrottledQueue,
Arbiter.Receive(true, intPort,
delegate(int i)
{
// only some items will be received since throttling will discard most of them
Console.WriteLine(i);
})
);
// post items as fast as possible so that the depth policy is activated and discards
// all the oldest items in the dispatcher queue
for (int i = ; i < maximumDepth * ; i++)
{
intPort.Post(i);
}
}
/// <summary>
/// Handler that executes in parallel with main application thread
/// </summary>
/// <param name="signal"></param>
void SomeTask(AutoResetEvent signal)
{
try
{
for (int i = ; i < ; i++)
{
int k = i * i / ;
}
}
finally
{
// done, signal main application thread
signal.Set();
}
}
在上面的例子中,我们演示了一个使用操作系统事件来阻塞应用程序主线程的小例子。
简化.NET异步编程模式
CCR可以用于任何实现了异步变成模型模式的.net类型。它实际上极大的简化了异步模式,并且当用于C#时,完全不再需要delegate和接续传递(continuation passing)。CCR迭带器调度支持允许你直接返回并继续(yield)挂起的I/O操作并且实现的易读的代码和过去只能在同步代码中实现的模式。
例27.
IEnumerator<ITask> CcrReadEnumerator(string filename)
{
var resultPort = new Port<IAsyncResult>();
// stage 1: open file and start the asynchronous operation
using (FileStream fs = new FileStream(filename,
FileMode.Open, FileAccess.Read, FileShare.Read, , FileOptions.Asynchronous))
{
Byte[] data = new Byte[fs.Length];
fs.BeginRead(data, , data.Length, resultPort.Post, null);
// stage 2: suspend execution until operation is complete
yield return Arbiter.Receive(false, resultPort, delegate { });
// stage 3: retrieve result of operation just by assigned variable to CCR port
var ar = (IAsyncResult)resultPort;
try
{ Int32 bytesRead = fs.EndRead(ar); }
catch
{
// handle I/O exception
}
ProcessData(data);
}
}
例子27演示了CCR如何使用文件流的异步编程模型BeginRead/EndRead方法而又不需要传递delegate。取而代之的是,我们提供一个CCR Port的Post方法,所以异步结果被直接投递到一个CCR Port。代码返回并继续在一个port上进行接受操作。yield return语句允许我们编写逻辑上顺序的代码而不需要使用一个操作系统线程。代码保留了异步的可伸缩性和overlapped操作,但是读起来就像是同步、顺序的代码。
/// <summary>
/// Read from one stream into a Http request stream, asynchronously
/// </summary>
public virtual IEnumerator<ITask> UploadHttpStream(string contentUrl,
Stream contentStream, PortSet<HttpStatusCode, Exception> resultPort)
{
// Create HTTP request
HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(contentUrl);
webRequest.Method = "POST";
HttpStatusCode status = HttpStatusCode.OK;
Exception ex = null;
using (Stream requestStream = webRequest.GetRequestStream())
{
byte[] readBuffer = new byte[];
int bytesRead = -;
// With CCR and iterators you can do loops and asynchronous I/O
do
{
// use CCR stream adapter (or a custom APM adapter) to schedule operation
var ioResultPort = StreamAdapter.Read(contentStream, readBuffer, , );
// yield to result (success or failure)
yield return (Choice)ioResultPort;
// check for error
ex = ioResultPort;
if (ex != null)
{
resultPort.Post(ex);
// exit on error
yield break;
}
bytesRead = ioResultPort;
var writeResultPort = StreamAdapter.Write(requestStream, readBuffer, , bytesRead);
// yield to write operation
yield return (Choice)writeResultPort;
// check for write error
ex = writeResultPort;
if (ex != null)
{
resultPort.Post(ex);
yield break;
}
} while (bytesRead > );
requestStream.Flush();
}
// Use built-in CCR adapter for reading HTTP response
var webResultPort = WebRequestAdapter.ReadResponse(webRequest, _taskQueue);
// yield to web response operation
yield return (Choice)webResultPort;
// check for any exceptions
GetErrorDetails((Exception)webResultPort, out status);
resultPort.Post(status);
}
参考
MSDN Magazine: Concurrent Affairs -- Concurrency and Coordination Runtime
与非CCR代码互操作的更多相关文章
- Java类加载信息的顺序:包括静态代码快、静态类变量、非静态代码快、构造方法、普通方法
JVM运行之前会执行一个叫做类加载器的子系统,叫做ClassLoader,那么类里面那么多“元素”,究竟是个什么顺序呢,写几行代码测试一下,通过给每个方法和代码快和静态变量打上断点来测试: class ...
- ARC代码和非ARC代码 混用
选中工程->TARGETS->相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了.然后在相应的文件后面添加:-fobjc-arc参 ...
- java 子类、父类中静态代码块、字段,非静态代码块、字段以及构造函数的初始化顺序和次数
一个类中的数据初始化顺序是面试官非常喜欢出的面试题之一,本文用一个实例来介绍java中子类.父类中静态代码块.字段,非静态代码块.字段以及构造函数的执行顺序和次数. 一.包结构
- 使用非java代码编程
使用非JAVA代码 JAVA语言及其标准API(应用程序编程接口)应付应用程序的编写已绰绰有余.但在某些情况下,还是必须使用非JAVA编码.例如,我们有时要访问操作系统的专用特性,与特殊的硬件 ...
- Java静态代码块与非静态代码块
静态代码块,格式是 static{ },随着类的加载而加载,且只执行一次. 在程序中,执行的优先级最高. 非静态代码块,格式是{ },在创建对象的时候运行(即new一个对象的时候),每创建一次对象就执 ...
- Java非静态代码块和静态代码块
类中存在两种特殊的代码块,即非静态代码块和静态代码块,前者是直接由 { } 括起来的代码,而后者是由 static{ } 括起来的代码. 非静态代码块在类初始化创建实例时,将会被提取到类的构造器中执行 ...
- Java中静态变量、静态代码块、非静态代码块以及静态方法的加载顺序
在研究单例设计模式的时候,用到了静态变量和静态方法的内容,出于兴趣,这里简单了解一下这四个模块在类初始化的时候的加载顺序. 经过研究发现,它们的加载顺序为: 1.非静态代码块 2.静态变量或者静态代码 ...
- 关于一致/非一致代码段与TSS 关系的个人看法
[0]概念定义 0.1)一致代码段: 简单理解,就是操作系统拿出来被共享的代码段,可以被低特权级的用户直接调用访问的代码, 但是特权级高的程序不允许访问特权级低的数据. 通常这些共享代码,是" ...
- node总结--回调函数阻塞和非阻塞代码实例
阻塞代码实例: var fs = require("fs"); var data = fs.readFileSync('input.txt'); console.log(data. ...
随机推荐
- WebView重定向新开界面问题-b
首先介绍下这个问题,iOS上WebView 如果想更贴近native,就要加载新URL的时候新开个界面,但是如果加载的链接有重定向的话,就会在中间开一个空白的界面,这个好烦.然后就是解决这个问题,采用 ...
- linux内核分析之进程地址空间管理
1.struct task_struct 进程内核栈是操作系统为管理每一个进程而分配的一个4k或者8k内存大小的一片内存区域,里面存放了一个进程的所有信息,它能够完整的描述一个正在执行的程序:它打开的 ...
- tcpprep 对IPV6的支持
在采用tcpreplay对包实施回放前,需要对包执行预处理,tcpprep就是完成这个任务的.tcpprep要做的处理就是生成一个cache文件,根据tcpprep wiki的介绍http://tcp ...
- 解决Maven不能下载“oracle、aspectjweaver、com.springsource.net.sf.cglib”jar
鸣谢网址:http://www.cnblogs.com/dongyangbolg/p/3455422.html http://www.cnblogs.com/ysq0908/p/4737977.htm ...
- CSRF手工测试方法
CSRF(Cross-site request forgery),中文名称:跨站请求伪造,也被称为:one click attack/session riding,缩写为:CSRF/XSRF.一般来说 ...
- android 使用系统照相程序照相并存储、显示在界面上
大部分业务可以通过调用系统的相机程序来拍照. 界面如下: <?xml version="1.0" encoding="utf-8"?> <Li ...
- jmeter 测试java协议经验总结
对java协议的良好支持,是jmeter比loadrunner优秀的地方,但是坑也不少,本文将相关点都整理下来备忘 一. 依赖的jar包 使用IDE开发jemter java协议脚本时,需要导入以下几 ...
- 2.Adding a Controller
MVC stands for model-view-controller. MVC is a pattern for developing applications that are well ar ...
- 【疯狂Java学习笔记】【理解面向对象】
[学习笔记]1.Java语言是纯粹的面向对象语言,这体现在Java完全支持面向对象的三大基本特征:封装.继承.多态.抽象也是面向对象的重要组成部分,不过它不是面向对象的特征之一,因为所有的编程语言都需 ...
- 200. Number of Islands
题目: Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is s ...