AppDomain 類別
定義
重要
部分資訊涉及發行前產品,在發行之前可能會有大幅修改。 Microsoft 對此處提供的資訊,不做任何明確或隱含的瑕疵擔保。
表示應用程式定義域,也就是應用程式執行的獨立環境。 此類別無法獲得繼承。
public ref class AppDomain sealed : MarshalByRefObject
public ref class AppDomain : MarshalByRefObject
public ref class AppDomain sealed : MarshalByRefObject, _AppDomain, System::Security::IEvidenceFactory
public sealed class AppDomain : MarshalByRefObject
public class AppDomain : MarshalByRefObject
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
public sealed class AppDomain : MarshalByRefObject, _AppDomain, System.Security.IEvidenceFactory
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class AppDomain : MarshalByRefObject, _AppDomain, System.Security.IEvidenceFactory
[System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)]
[System.Runtime.InteropServices.ComVisible(true)]
public sealed class AppDomain : MarshalByRefObject
type AppDomain = class
inherit MarshalByRefObject
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
type AppDomain = class
inherit MarshalByRefObject
interface _AppDomain
interface IEvidenceFactory
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type AppDomain = class
inherit MarshalByRefObject
interface _AppDomain
interface IEvidenceFactory
[<System.Runtime.InteropServices.ClassInterface(System.Runtime.InteropServices.ClassInterfaceType.None)>]
[<System.Runtime.InteropServices.ComVisible(true)>]
type AppDomain = class
inherit MarshalByRefObject
Public NotInheritable Class AppDomain
Inherits MarshalByRefObject
Public Class AppDomain
Inherits MarshalByRefObject
Public NotInheritable Class AppDomain
Inherits MarshalByRefObject
Implements _AppDomain, IEvidenceFactory
- 繼承
- 屬性
- 實作
範例
這個範例示範如何建立新的 、在該新的 AppDomain AppDomain 中具現化類型,並與該類型的 物件通訊。 此外,此範例示範如何卸載 AppDomain 造成物件被垃圾收集的 。
using namespace System;
using namespace System::Reflection;
using namespace System::Threading;
using namespace System::Security::Policy;
// Because this class is derived from MarshalByRefObject, a proxy
// to a MarshalByRefType object can be returned across an AppDomain
// boundary.
ref class MarshalByRefType : MarshalByRefObject
{
public:
// Call this method via a proxy.
void SomeMethod(String^ callingDomainName)
{
// Get this AppDomain's settings and display some of them.
AppDomainSetup^ ads = AppDomain::CurrentDomain->SetupInformation;
Console::WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}",
ads->ApplicationName,
ads->ApplicationBase,
ads->ConfigurationFile
);
// Display the name of the calling AppDomain and the name
// of the second domain.
// NOTE: The application's thread has transitioned between
// AppDomains.
Console::WriteLine("Calling from '{0}' to '{1}'.",
callingDomainName,
Thread::GetDomain()->FriendlyName
);
};
};
void main()
{
// Get and display the friendly name of the default AppDomain.
String^ callingDomainName = Thread::GetDomain()->FriendlyName;
Console::WriteLine(callingDomainName);
// Get and display the full name of the EXE assembly.
String^ exeAssembly = Assembly::GetEntryAssembly()->FullName;
Console::WriteLine(exeAssembly);
// Construct and initialize settings for a second AppDomain.
AppDomainSetup^ ads = gcnew AppDomainSetup();
ads->ApplicationBase = AppDomain::CurrentDomain->BaseDirectory;
ads->DisallowBindingRedirects = false;
ads->DisallowCodeDownload = true;
ads->ConfigurationFile =
AppDomain::CurrentDomain->SetupInformation->ConfigurationFile;
// Create the second AppDomain.
AppDomain^ ad2 = AppDomain::CreateDomain("AD #2",
AppDomain::CurrentDomain->Evidence, ads);
// Create an instance of MarshalbyRefType in the second AppDomain.
// A proxy to the object is returned.
MarshalByRefType^ mbrt =
(MarshalByRefType^) ad2->CreateInstanceAndUnwrap(
exeAssembly,
MarshalByRefType::typeid->FullName
);
// Call a method on the object via the proxy, passing the
// default AppDomain's friendly name in as a parameter.
mbrt->SomeMethod(callingDomainName);
// Unload the second AppDomain. This deletes its object and
// invalidates the proxy object.
AppDomain::Unload(ad2);
try
{
// Call the method again. Note that this time it fails
// because the second AppDomain was unloaded.
mbrt->SomeMethod(callingDomainName);
Console::WriteLine("Sucessful call.");
}
catch(AppDomainUnloadedException^)
{
Console::WriteLine("Failed call; this is expected.");
}
}
/* This code produces output similar to the following:
AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from 'AppDomainX.exe' to 'AD #2'.
Failed call; this is expected.
*/
using System;
using System.Reflection;
using System.Threading;
class Module1
{
public static void Main()
{
// Get and display the friendly name of the default AppDomain.
string callingDomainName = Thread.GetDomain().FriendlyName;
Console.WriteLine(callingDomainName);
// Get and display the full name of the EXE assembly.
string exeAssembly = Assembly.GetEntryAssembly().FullName;
Console.WriteLine(exeAssembly);
// Construct and initialize settings for a second AppDomain.
AppDomainSetup ads = new AppDomainSetup();
ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory;
ads.DisallowBindingRedirects = false;
ads.DisallowCodeDownload = true;
ads.ConfigurationFile =
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;
// Create the second AppDomain.
AppDomain ad2 = AppDomain.CreateDomain("AD #2", null, ads);
// Create an instance of MarshalbyRefType in the second AppDomain.
// A proxy to the object is returned.
MarshalByRefType mbrt =
(MarshalByRefType) ad2.CreateInstanceAndUnwrap(
exeAssembly,
typeof(MarshalByRefType).FullName
);
// Call a method on the object via the proxy, passing the
// default AppDomain's friendly name in as a parameter.
mbrt.SomeMethod(callingDomainName);
// Unload the second AppDomain. This deletes its object and
// invalidates the proxy object.
AppDomain.Unload(ad2);
try
{
// Call the method again. Note that this time it fails
// because the second AppDomain was unloaded.
mbrt.SomeMethod(callingDomainName);
Console.WriteLine("Sucessful call.");
}
catch(AppDomainUnloadedException)
{
Console.WriteLine("Failed call; this is expected.");
}
}
}
// Because this class is derived from MarshalByRefObject, a proxy
// to a MarshalByRefType object can be returned across an AppDomain
// boundary.
public class MarshalByRefType : MarshalByRefObject
{
// Call this method via a proxy.
public void SomeMethod(string callingDomainName)
{
// Get this AppDomain's settings and display some of them.
AppDomainSetup ads = AppDomain.CurrentDomain.SetupInformation;
Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}",
ads.ApplicationName,
ads.ApplicationBase,
ads.ConfigurationFile
);
// Display the name of the calling AppDomain and the name
// of the second domain.
// NOTE: The application's thread has transitioned between
// AppDomains.
Console.WriteLine("Calling from '{0}' to '{1}'.",
callingDomainName,
Thread.GetDomain().FriendlyName
);
}
}
/* This code produces output similar to the following:
AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from 'AppDomainX.exe' to 'AD #2'.
Failed call; this is expected.
*/
open System
open System.Reflection
open System.Threading
// Because this class is derived from MarshalByRefObject, a proxy
// to a MarshalByRefType object can be returned across an AppDomain
// boundary.
type MarshalByRefType() =
inherit MarshalByRefObject()
// Call this method via a proxy.
member _.SomeMethod(callingDomainName) =
// Get this AppDomain's settings and display some of them.
let ads = AppDomain.CurrentDomain.SetupInformation
printfn $"AppName={ads.ApplicationName}, AppBase={ads.ApplicationBase}, ConfigFile={ads.ConfigurationFile}"
// Display the name of the calling AppDomain and the name
// of the second domain.
// NOTE: The application's thread has transitioned between
// AppDomains.
printfn $"Calling from '{callingDomainName}' to '{Thread.GetDomain().FriendlyName}'."
// Get and display the friendly name of the default AppDomain.
let callingDomainName = Thread.GetDomain().FriendlyName
printfn $"{callingDomainName}"
// Get and display the full name of the EXE assembly.
let exeAssembly = Assembly.GetEntryAssembly().FullName
printfn $"{exeAssembly}"
// Construct and initialize settings for a second AppDomain.
let ads = AppDomainSetup()
ads.ApplicationBase <- AppDomain.CurrentDomain.BaseDirectory
ads.DisallowBindingRedirects <- false
ads.DisallowCodeDownload <- true
ads.ConfigurationFile <-
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
// Create the second AppDomain.
let ad2 = AppDomain.CreateDomain("AD #2", null, ads)
// Create an instance of MarshalbyRefType in the second AppDomain.
// A proxy to the object is returned.
let mbrt =
ad2.CreateInstanceAndUnwrap(
exeAssembly,
typeof<MarshalByRefType>.FullName) :?> MarshalByRefType
// Call a method on the object via the proxy, passing the
// default AppDomain's friendly name in as a parameter.
mbrt.SomeMethod callingDomainName
// Unload the second AppDomain. This deletes its object and
// invalidates the proxy object.
AppDomain.Unload ad2
try
// Call the method again. Note that this time it fails
// because the second AppDomain was unloaded.
mbrt.SomeMethod callingDomainName
printfn "Sucessful call."
with :? AppDomainUnloadedException ->
printfn "Failed call this is expected."
(* This code produces output similar to the following:
AppDomainX.exe
AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
Calling from 'AppDomainX.exe' to 'AD #2'.
Failed call this is expected.
*)
Imports System.Reflection
Imports System.Threading
Module Module1
Sub Main()
' Get and display the friendly name of the default AppDomain.
Dim callingDomainName As String = Thread.GetDomain().FriendlyName
Console.WriteLine(callingDomainName)
' Get and display the full name of the EXE assembly.
Dim exeAssembly As String = [Assembly].GetEntryAssembly().FullName
Console.WriteLine(exeAssembly)
' Construct and initialize settings for a second AppDomain.
Dim ads As New AppDomainSetup()
ads.ApplicationBase = AppDomain.CurrentDomain.BaseDirectory
ads.DisallowBindingRedirects = False
ads.DisallowCodeDownload = True
ads.ConfigurationFile = _
AppDomain.CurrentDomain.SetupInformation.ConfigurationFile
' Create the second AppDomain.
Dim ad2 As AppDomain = AppDomain.CreateDomain("AD #2", Nothing, ads)
' Create an instance of MarshalbyRefType in the second AppDomain.
' A proxy to the object is returned.
Dim mbrt As MarshalByRefType = CType( _
ad2.CreateInstanceAndUnwrap(exeAssembly, _
GetType(MarshalByRefType).FullName), MarshalByRefType)
' Call a method on the object via the proxy, passing the default
' AppDomain's friendly name in as a parameter.
mbrt.SomeMethod(callingDomainName)
' Unload the second AppDomain. This deletes its object and
' invalidates the proxy object.
AppDomain.Unload(ad2)
Try
' Call the method again. Note that this time it fails because
' the second AppDomain was unloaded.
mbrt.SomeMethod(callingDomainName)
Console.WriteLine("Sucessful call.")
Catch e As AppDomainUnloadedException
Console.WriteLine("Failed call; this is expected.")
End Try
End Sub
End Module
' Because this class is derived from MarshalByRefObject, a proxy
' to a MarshalByRefType object can be returned across an AppDomain
' boundary.
Public Class MarshalByRefType
Inherits MarshalByRefObject
' Call this method via a proxy.
Public Sub SomeMethod(ByVal callingDomainName As String)
' Get this AppDomain's settings and display some of them.
Dim ads As AppDomainSetup = AppDomain.CurrentDomain.SetupInformation
Console.WriteLine("AppName={0}, AppBase={1}, ConfigFile={2}", _
ads.ApplicationName, ads.ApplicationBase, ads.ConfigurationFile)
' Display the name of the calling AppDomain and the name
' of the second domain.
' NOTE: The application's thread has transitioned between
' AppDomains.
Console.WriteLine("Calling from '{0}' to '{1}'.", _
callingDomainName, Thread.GetDomain().FriendlyName)
End Sub
End Class
'This code produces output similar to the following:
'
' AppDomainX.exe
' AppDomainX, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
' AppName=, AppBase=C:\AppDomain\bin, ConfigFile=C:\AppDomain\bin\AppDomainX.exe.config
' Calling from 'AppDomainX.exe' to 'AD #2'.
' Failed call; this is expected.
備註
由 物件表示 AppDomain 的應用程式域,可協助提供隔離、卸載和安全性界限來執行 Managed 程式碼。
使用應用程式域來隔離可能會關閉進程的工作。 如果執行工作的 狀態 AppDomain 變得不穩定,則可以卸載 , AppDomain 而不會影響進程。 當進程必須長時間執行而不重新開機時,這很重要。 您也可以使用應用程式域來隔離不應該共用資料的工作。
如果元件載入預設應用程式域,則無法在進程執行時從記憶體卸載。 不過,如果您開啟第二個應用程式域以載入和執行元件,則會在卸載該應用程式域時卸載該元件。 使用此技術可將偶爾使用大型 DLL 之長時間執行進程的工作集降到最低。
注意
在 .NET Core 上,實 AppDomain 作會受到設計限制,而且不會提供隔離、卸載或安全性界限。 針對 .NET Core,只有一個 AppDomain 。 隔離和卸載是透過 AssemblyLoadContext 提供。 安全性界限應由進程界限和適當的遠端技術提供。
多個應用程式域可以在單一進程中執行;不過,應用程式域和執行緒之間沒有一對一相互關聯。 數個執行緒可以屬於單一應用程式域,而指定的執行緒不限於單一應用程式域,但在任何指定的時間,執行緒會在單一應用程式域中執行。
應用程式域是使用 CreateDomain 方法建立的。 AppDomain 實例可用來載入和執行 (Assembly) 的元件。 AppDomain當 不再使用 時,可以卸載它。
類別 AppDomain 會實作一組事件,讓應用程式在載入元件、卸載應用程式域時或擲回未處理的例外狀況時回應。
如需使用應用程式域的詳細資訊,請參閱 應用程式域。
這個類別會實作 MarshalByRefObject 、 _AppDomain 和 IEvidenceFactory 介面。
您不應該為 AppDomain 物件建立可遠端包裝函式。 這麼做可以發佈該 AppDomain 的遠端參考,公開遠端存取之類的 CreateInstance 方法,並有效地終結該 AppDomain 的程式碼存取安全性。 連線到遠端 AppDomain 的惡意用戶端可以存取本身可存取的任何資源 AppDomain 。 請勿針對任何擴充 MarshalByRefObject 及實作惡意用戶端可用來略過安全性系統的方法,建立可遠端包裝函式。
警告
屬性的 AppDomainSetup.DisallowCodeDownload 預設值為 false
。 此設定對服務而言不安全。 若要防止服務下載部分信任的程式碼,請將此屬性設定為 true
。
屬性
ActivationContext |
取得目前應用程式定義域的啟動內容。 |
ApplicationIdentity |
取得應用程式定義域中的應用程式之識別。 |
ApplicationTrust |
取得資訊,以描述授與應用程式的權限,以及該應用程式是否有允許其執行的信任層級。 |
BaseDirectory |
取得組件解析程式 (Resolver) 用來探查組件的基底目錄。 |
CurrentDomain |
取得目前 Thread 的目前應用程式定義域。 |
DomainManager |
取得在已經初始化應用程式定義域時,由主應用程式提供的定義域管理員。 |
DynamicDirectory |
取得組件解析程式用來探查動態建立之組件的目錄。 |
Evidence |
取得與此應用程式定義域相關聯的 Evidence。 |
FriendlyName |
取得應用程式定義域的易記名稱。 |
Id |
取得可唯一識別處理序中之應用程式定義域的整數。 |
IsFullyTrusted |
取得值,該值指出載入目前應用程式定義域中的組件是否在完全信任情況下執行。 |
IsHomogenous |
取得值,這個值表示目前應用程式定義域是否會授與一組權限給所有載入該應用程式定義域中的組件。 |
MonitoringIsEnabled |
取得或設定值,這個值表示是否對目前處理序啟用應用程式定義域的 CPU 和記憶體監視。 一旦對處理序啟用監視,就不能停用。 |
MonitoringSurvivedMemorySize |
取得自上次回收作業後存留下來,且已知正由目前應用程式定義域參考之位元組的數目。 |
MonitoringSurvivedProcessMemorySize |
針對處理序中的所有應用程式定義域,取得自上次回收作業存留下來的位元組總數。 |
MonitoringTotalAllocatedMemorySize |
取得應用程式定義域自其建立後已配置之所有記憶體的總大小 (以位元組為單位),但不減去已回收的記憶體。 |
MonitoringTotalProcessorTime |
取得自處理程序啟動後,所有執行緒在目前應用程式定義域中執行時用掉的處理器時間總計。 |
PermissionSet |
已過時。
取得沙箱應用程式定義域的權限集。 |
RelativeSearchPath |
取得組件解析程式應該在其中探查私用組件的路徑,此路徑位於基底目錄下。 |
SetupInformation |
取得這個執行個體的應用程式定義域組態資訊。 |
ShadowCopyFiles |
取得是否已設定應用程式定義域以進行檔案陰影複製的指示。 |
方法
事件
AssemblyLoad |
發生於載入組件時。 |
AssemblyResolve |
發生於組件解析失敗時。 |
DomainUnload |
發生於將要卸載 AppDomain 時。 |
FirstChanceException |
發生於執行階段在呼叫堆疊中搜尋應用程式定義域的例外狀況處理常式之前,在 Managed 程式碼中擲回例外狀況時。 |
ProcessExit |
發生於預設應用程式定義域的父處理程序結束時。 |
ReflectionOnlyAssemblyResolve |
發生於僅限反映之內容中的組件解析失敗時。 |
ResourceResolve |
發生於資源的解析失敗時 (原因是因為該資源在組件中不是有效連結或內嵌的資源)。 |
TypeResolve |
發生於類型解析失敗時。 |
UnhandledException |
發生於未攔截到例外狀況時。 |
明確介面實作
_AppDomain.GetIDsOfNames(Guid, IntPtr, UInt32, UInt32, IntPtr) |
將一組名稱對應至一組對應的分派識別項 (Dispatch Identifier)。 |
_AppDomain.GetTypeInfo(UInt32, UInt32, IntPtr) |
擷取物件的類型資訊,可以用來取得介面的類型資訊。 |
_AppDomain.GetTypeInfoCount(UInt32) |
擷取物件提供的類型資訊介面數目 (0 或 1)。 |
_AppDomain.Invoke(UInt32, Guid, UInt32, Int16, IntPtr, IntPtr, IntPtr, IntPtr) |
提供物件所公開的屬性和方法的存取權。 |