技术开发 频道

.NET 组件中的线程辅助


    InprocServer32下面的ThreadingModel钥有一个'Both'值。在Classic COM中,把它们的ThreadingModel作为'Both'的对象,期望移到它们的呼叫者单元,此呼叫者单元可以是STA或者MTA。除此以外,'Both'线程对象也集合自由线程封送拆收器,给被它们封送拆收事物提供单元,也集合直接接口指针引用,以此反对代理。Context Agile .NET 组件(不是从ContextBound对象扩展而来的)与中立线程COM对象相似,此中立线程COM对象集合自由线程封送拆收器。当我们通过非托管客户端中的COM 单元将接口引用传输到.NET组件时,.NET组件是怎样运行的。让我们看一下这个简单的C#类型:将向非托管 COM客户端展示这个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运行到这个对象下载的事物里。为了把上面的类型建成一个程序集,为COM创建正确注册途径,从命令行中执行下列命令。

csc /target:library /out:HelloDotNet.dll HelloDotNet.cs 
regasm HelloDotNet.dll /tlb:HelloDotNet.tlb
   现在继续使用来自于COM 感知客户端的.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_pStream1 = NULL;
IStream* g_pStream2 = 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_pStream1);

hr = CoMarshalInterThreadInterfaceInStream(_uuidof(IHelloDotNet),
spHelloNET,
&g_pStream2);

hThreadSTA = CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)MySTAThreadFunction,
NULL,0 ,&dwThreadIDSTA);

cout << "The Thread ID of the STA based Worker thread is : "
<< dwThreadIDSTA << endl;

hThreadMTA = CreateThread(NULL,0,
(LPTHREAD_START_ROUTINE)MyMTAThreadFunction,
NULL,0,&dwThreadIDMTA);

cout << "The Thread ID of the MTA based Worker thread is : "
<< dwThreadIDMTA << endl;
0
相关文章