知识大全 .NET组件中的线程辅助的学习
Posted 知
篇首语:青春须早为,岂能长少年。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 .NET组件中的线程辅助的学习相关的知识,希望对你有一定的参考价值。
.NET组件中的线程辅助的学习 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
在Understanding Threading Models and Apartments from a NET Application s perspective 这一章 你知道在创建经典组件之前 NET 应用程序是怎样宣告调用线程单元辅助 现在看一下等式的另一方面 尤其是当从非托管 感知应用程序创建了 NET组件时 NET组件的线程辅助被文本定义 而对象就处在这个文本中 本质上来说 一个Context就是AppDomain(轻型过程)拥有的环境 而对象就是在AppDomain 中创建的 每一个文本都依次拥有对象 这些对象享用公共的使用要求 例如 线程辅助 对象池化 交易 JIT 激活 同步等 当依靠属性的执行时要求时 而且对象也要求中断服务时 就会创建这些文本 如果这里有一个文本 此嗯本与使用规则相匹配 然后执行时就会在那个文本中提供调节 如果它没有找到一个相匹配的文本 就会为对象创建一个新文本
前面说到 每一个AppDomain都有一个默认文本 默认文本 依次拥有Context Agnostic (Context Agile)对象 这些对象没有绑定到任何文本 Context Agile 对象不要求任何属性 特殊使用规则以及中断服务 让我们看一下下面的表格 此表格总结了基于它们自己文本敏捷度的跨文本访问方案中 NET 组件是怎样执行的
图被非托管感知客户端访问时的线程中立行为
当一个程序集经过REGASM EXE 想为 感知客户端创建正确的注册途径时 NET组件是怎样把它的线程模式转到的
InprocServer 下面的ThreadingModel钥有一个 Both 值 在Classic 中 把它们的ThreadingModel作为 Both 的对象 期望移到它们的呼叫者单元 此呼叫者单元可以是STA或者MTA 除此以外 Both 线程对象也集合自由线程封送拆收器 给被它们封送拆收事物提供单元 也集合直接接口指针引用 以此反对代理 Context Agile NET 组件(不是从ContextBound对象扩展而来的)与中立线程对象相似 此中立线程对象集合自由线程封送拆收器 当我们通过非托管客户端中的 单元将接口引用传输到 NET组件时 NET组件是怎样运行的 让我们看一下这个简单的C#类型 将向非托管 客户端展示这个C#类型
using System; using System Runtime InteropServices; public interface IHelloDotNet String GetThreadID(); /* end interface IHelloDotNet */ [ClassInterface(ClassInterfaceType None)] public class HelloDotNet : IHelloDotNet public HelloDotNet() public String GetThreadID() return AppDomain GetCurrentThreadId() ToString(); /* end class HelloDotNet */
上面的类型执行来自于IHelloDotNet接口的GetThreadID方法 这个方法返回当前线程的ID 此当前线程正将AppDomain运行到这个对象下载的事物里 为了把上面的类型建成一个程序集 为创建正确注册途径 从命令行中执行下列命令
csc /target:library /out:HelloDotNet dll HelloDotNet cs regasm HelloDotNet dll /tlb:HelloDotNet tlb
现在继续使用来自于感知客户端的 NET组件 我们将使用一个C++ 控制台应用程序 此C++ 控制台应用程序将在它的主线程 (一个STA)中创建 NET组件 然后通过生成其它两个背景工作执行绪 把它传送到另外两个单元(一个STA单元和一个MTA单元)
让我们看一下 当使用显式线程间封送拆收调用(此调用使用CoMarshalInterface/CoUnmarshalInterface API家族)时 什么时候被封送拆收的引用将在单元传输 看一下下面的代码(为了简洁 省略了代码中的错误检查)
Collapse #import mscorlib tlb // 导入 NET 组件 #import HelloDotNet tlb no_namespace // 线程函数 long WINAPI MySTAThreadFunction(long lParam); long WINAPI MyMTAThreadFunction(long lParam); IHelloDotNetPtr spHelloNET = NULL; IStream* g_pStream = NULL; IStream* g_pStream = NULL; int main(int argc char* argv[]) ::CoInitialize(NULL); cout << The Thread ID of the primary STA thread is : << ::GetCurrentThreadId() << endl; hr = spHelloNET CreateInstance(__uuidof(HelloDotNet)); cout << From NET when called from the primary STA Thread : << spHelloNET >GetThreadID() << endl; hr = CoMarshalInterThreadInterfaceInStream(_uuidof(IHelloDotNet) spHelloNET &g_pStream ); hr = CoMarshalInterThreadInterfaceInStream(_uuidof(IHelloDotNet) spHelloNET &g_pStream ); hThreadSTA = CreateThread(NULL (LPTHREAD_START_ROUTINE)MySTAThreadFunction NULL &dwThreadIDSTA); cout << The Thread ID of the STA based Worker thread is : << dwThreadIDSTA << endl; hThreadMTA = CreateThread(NULL (LPTHREAD_START_ROUTINE)MyMTAThreadFunction NULL &dwThreadIDMTA); cout << The Thread ID of the MTA based Worker thread is : << dwThreadIDMTA << endl;
::WaitForSingleobject(hThreadSTA INFINITE); ::WaitForSingleobject (hThreadMTA INFINITE); return ; long WINAPI MySTAThreadFunction(long lParam) ::CoInitializeEx(NULL COINIT_APARTMENTTHREADED); cout << From NET when called from the STA Worker Thread (Direct Access) : << spHelloNET >GetThreadID() << endl; IHelloDotNetPtr spHello = NULL; HRESULT hr = CoGetInterfaceAndReleaseStream(g_pStream __uuidof(IHelloDotNet) (void **)&spHello); if(S_OK == hr) cout << From NET when called from the STA Worker Thread (Marshaled) : << spHello >GetThreadID() << endl; return ; long WINAPI MyMTAThreadFunction(long lParam) // 让线程进入MTA ::CoInitializeEx(NULL COINIT_MULTITHREADED); cout << From NET when called from the MTA Worker Thread (Direct Access) : << spHelloNET >GetThreadID() << endl; IHelloDotNetPtr spHello = NULL; HRESULT hr = CoGetInterfaceAndReleaseStream(g_pStream __uuidof(IHelloDotNet) (void **)&spHello); if(S_OK == hr) cout << From NET when called from the MTA Worker Thread (Marshaled) : << spHello >GetThreadID() << endl; // 从线程退出 return ; /* 结束MyMTAThreadFunction */
当运行控制台应用程序时 这是得到的输出
The Thread ID of the primary STA thread is : From NET when called from the primary STA Thread : The Thread ID of the STA based Worker thread is : The Thread ID of the MTA based Worker thread is : From NET when called from the STA Worker Thread (Direct Access) : From NET when called from the STA Worker Thread (Marshalled) : From NET when called from the MTA Worker Thread (Direct Access) : From NET when called from the MTA Worker Thread (Marshalled) :
注意 对于所有调用 在客户端中的线程呼叫之间 不会产生线程交换 在 NET组件中 也不会产生线程引发实际方法 还句话说 NET组件是一个Context agile 总是在呼叫者线程里执行任务 从上面的代码片段中观察到 对象引用(例如 CoMarshalInterThreadInterfaceInStream/CoGetInterfaceAndReleaseStream)的封送拆收效果与在单元间传递直接对象引用的效果是一样的 最后 接受单元得到一个中立单元接口指针 此中立单元l接口指针能用来调用 NET组件 NET组件展示Both 线程Classic 组件回忆的所有行为 而Both线程Classic 组件则集合the自由线程封送拆收器
结论 NET世界中组件的地位
在这系列文章的第一部分 我们可以怎样把Classic 组件展示到在公共语言运行库 (通用语言执行层)范围内执行的 NET应用程序 通过使用前期绑定和晚期绑定 以及检查执行时类型和创建动态类型发现的方法 interop怎样无缝地允许你来调用你的组件 我们已经理解了在 NET 中 委托是怎样工作的 以及它们在 NET时间处理模式中所扮演的角色 以及作为适配器 Interop是怎样把classic 中的连接点事件处理模式连接到 NET中的基于委托的事件处理模式 我们讨论了怎样把集合展示到 NET应用程序中 以及怎样使用C# s foreach句法简单地通过集合元素来迭代 然后 我们研究了IDL文件中的方向属性是怎样被映射到C#中相应的方向参数类型 我们也学习了 通过使用继承和内含包容 Classic 组件可以利用的来自于 NET 应用程序的重用选项 最后知道当调用组件时 托管线程是怎样宣告它们的单元辅助
cha138/Article/program/net/201311/13088相关参考
详解.NET编程中的线程冲突 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一什么是线程冲突
详解.NET编程过程中的线程冲突 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一什么是线程冲突
VB.NET中的组件开发源代码剖析 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!
详解.NET编程过程中的线程冲突[3] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 四互斥锁
详解.NET编程过程中的线程冲突[1] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一什么是线
详解.NET编程过程中的线程冲突[2] 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 比如说我在
第十三讲:关于.NET组件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! NET组件是什么 组
Asp.net组件设计浅论 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 一什么是组件? 查看
详解.NET4.0代码契约组件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 代码契约组件是对N
用VS.NET创建.NET可复用数据库组件 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 下面我