appdomain
指定托管应用程序的每个应用程序域应具有其自己的特定全局变量或静态成员变量的副本。 有关详细信息,请参阅应用程序域和 Visual C++。
每个应用程序域具有其自己的 per-appdomain 变量的副本。 在将程序集加载到应用程序域中时执行 appdomain 变量的构造函数,并在卸载应用程序域时执行析构函数。
如果希望公共语言运行时中进程内的所有应用程序域共享全局变量,请使用 __declspec(process)
修饰符。 __declspec(process)
默认情况下在 /clr 下有效。 “/clr:pure”和“/clr:safe”编译器选项在 Visual Studio 2015 中已弃用,并且在 Visual Studio 2017 中不受支持。
__declspec(appdomain)
仅在使用 /clr 编译器选项之一时有效。 只有全局变量、静态成员变量或静态局部变量可以使用 __declspec(appdomain)
进行标记。 将 __declspec(appdomain)
应用于托管类型的静态成员是错误的,因为它们始终具有此行为。
使用 __declspec(appdomain)
与使用线程本地存储 (TLS) 类似。 线程具有其自己的存储,就像应用程序域一样。 使用 __declspec(appdomain)
可确保全局变量在为此应用程序创建的每个应用程序域中都具有其自己的存储。
在将 per process 和 per appdomain 变量结合使用方面存在一些限制;有关详细信息,请参阅 process。
例如,在程序启动时,初始化所有 per-process 变量,然后初始化所有 per-appdomain 变量。 因此,当初始化 per-process 变量时,它不能依赖于任何 per-application 域变量的值。 混合使用(分配)per appdomain 和 per process 变量的做法不妥。
有关如何在特定应用程序域中调用函数的信息,请参阅 call_in_appdomain Function。
示例
// declspec_appdomain.cpp
// compile with: /clr
#include <stdio.h>
using namespace System;
class CGlobal {
public:
CGlobal(bool bProcess) {
Counter = 10;
m_bProcess = bProcess;
Console::WriteLine("__declspec({0}) CGlobal::CGlobal constructor", m_bProcess ? (String^)"process" : (String^)"appdomain");
}
~CGlobal() {
Console::WriteLine("__declspec({0}) CGlobal::~CGlobal destructor", m_bProcess ? (String^)"process" : (String^)"appdomain");
}
int Counter;
private:
bool m_bProcess;
};
__declspec(process) CGlobal process_global = CGlobal(true);
__declspec(appdomain) CGlobal appdomain_global = CGlobal(false);
value class Functions {
public:
static void change() {
++appdomain_global.Counter;
}
static void display() {
Console::WriteLine("process_global value in appdomain '{0}': {1}",
AppDomain::CurrentDomain->FriendlyName,
process_global.Counter);
Console::WriteLine("appdomain_global value in appdomain '{0}': {1}",
AppDomain::CurrentDomain->FriendlyName,
appdomain_global.Counter);
}
};
int main() {
AppDomain^ defaultDomain = AppDomain::CurrentDomain;
AppDomain^ domain = AppDomain::CreateDomain("Domain 1");
AppDomain^ domain2 = AppDomain::CreateDomain("Domain 2");
CrossAppDomainDelegate^ changeDelegate = gcnew CrossAppDomainDelegate(&Functions::change);
CrossAppDomainDelegate^ displayDelegate = gcnew CrossAppDomainDelegate(&Functions::display);
// Print the initial values of appdomain_global in all appdomains.
Console::WriteLine("Initial value");
defaultDomain->DoCallBack(displayDelegate);
domain->DoCallBack(displayDelegate);
domain2->DoCallBack(displayDelegate);
// Changing the value of appdomain_global in the domain and domain2
// appdomain_global value in "default" appdomain remain unchanged
process_global.Counter = 20;
domain->DoCallBack(changeDelegate);
domain2->DoCallBack(changeDelegate);
domain2->DoCallBack(changeDelegate);
// Print values again
Console::WriteLine("Changed value");
defaultDomain->DoCallBack(displayDelegate);
domain->DoCallBack(displayDelegate);
domain2->DoCallBack(displayDelegate);
AppDomain::Unload(domain);
AppDomain::Unload(domain2);
}
__declspec(process) CGlobal::CGlobal constructor
__declspec(appdomain) CGlobal::CGlobal constructor
Initial value
process_global value in appdomain 'declspec_appdomain.exe': 10
appdomain_global value in appdomain 'declspec_appdomain.exe': 10
__declspec(appdomain) CGlobal::CGlobal constructor
process_global value in appdomain 'Domain 1': 10
appdomain_global value in appdomain 'Domain 1': 10
__declspec(appdomain) CGlobal::CGlobal constructor
process_global value in appdomain 'Domain 2': 10
appdomain_global value in appdomain 'Domain 2': 10
Changed value
process_global value in appdomain 'declspec_appdomain.exe': 20
appdomain_global value in appdomain 'declspec_appdomain.exe': 10
process_global value in appdomain 'Domain 1': 20
appdomain_global value in appdomain 'Domain 1': 11
process_global value in appdomain 'Domain 2': 20
appdomain_global value in appdomain 'Domain 2': 12
__declspec(appdomain) CGlobal::~CGlobal destructor
__declspec(appdomain) CGlobal::~CGlobal destructor
__declspec(appdomain) CGlobal::~CGlobal destructor
__declspec(process) CGlobal::~CGlobal destructor
另请参阅
反馈
https://aka.ms/ContentUserFeedback。
即将发布:在整个 2024 年,我们将逐步淘汰作为内容反馈机制的“GitHub 问题”,并将其取代为新的反馈系统。 有关详细信息,请参阅:提交和查看相关反馈