.Net – Tìm hiểu về Application Domain (AppDomain)

Application Domain (viết tắt AppDomain, đây cũng là tên lớp tương ứng trong .Net) có mục đích tạo một môi trường cách ly nằm bên trong một process, tương tự như các process hoạt động trong cùng một hệ điều hành. Bạn có thể sử dụng AppDomain để nạp các assembly và thực thi các tác vụ một cách riêng biệt trong cùng process. Bài viết này sẽ cho bạn thấy cách thức sử dụng và các lợi ích mà AppDomain đem lại.

Lớp System.AppDomain

Mỗi process khi được thực thi đều tồn tại ít nhất một AppDomain mà bạn có thể truy xuất được thông qua property AppDomain.CurrentDomain. Tất nhiên AppDomain chính này sẽ được nạp assembly mscorlib của .Net để hoạt động.

Một process có thể chứa nhiều application domain và mỗi application domain này có thể chứa không hoặc nhiều Thread. Như hình minh họa sau:

Lớp System.AppDomain chứa khá nhiều thuộc tính và phương thức mà bạn có thể tìm hiểu chi tiết tại MSDN. Trong phần bên dưới, tôi sẽ giới thiệu một số ví dụ sử dụng AppDomain mà bạn có thể cần tới khi tạo ra các ứng dụng .Net.

Application domain có lợi ích gì?

Như trong phần giới thiệu, việc sử dụng AppDomain cũng giống như việc hệ điều hành sử dụng process để thực hiện các ứng dụng, tác vụ. Việc cách ly này giúp cho các ứng dụng hay tác vụ hoạt động độc lập và không bị ảnh hưởng lẫn nhau. Ví dụ khi một tác vụ bị lỗi, các tác vụ khác sẽ không bị ảnh hưởng và vẫn có thể hoạt động bình thường.

-          Bạn có thể ngừng một ứng dụng mà không phải tắt toàn bộ process.

-          Các ứng dụng hoạt động độc lập và không thể truy xuất trực tiếp đến nhau.

-          Các thông tin cấu hình, mức độ bảo mật của các ứng dụng được tách riêng biệt và không ảnh hưởng lẫn nhau.

-          Hạn chế tài nguyên hệ thống cần sử dụng nhờ việc thực thi nhiều ứng dụng chỉ trong một process.

Các ví dụ sử dụng AppDomain

Lấy các assembly được nạp vào trong AppDomain

Sử dụng phương thức AppDomain.GetAssemblies() để lấy về một mảng assembly được nạp vào trong một AppDomain tùy ý. Ví dụ này sử dụng thêm namespace System.Reflection, bạn có thể sử dụng reflection để đọc các thông tin của assembly thông qua bài viết “Kĩ thuật Reflection trong .Net”.

public static void Main()
{
    Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
    for(int i=0;i<assemblies.Length;i++)
    {
        Console.WriteLine("# {0}:\t {1}",i+1, assemblies[i].FullName);
    }
    Console.Read();
}

Output:

# 1:     mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
# 2:     AppDomainExample, Version=1.0.4168.38715, Culture=neutral, PublicKeyToken=null

Trong đó assembly thứ hai chính là ứng dụng mà tôi đang chạy ví dụ.

Lưu và lấy dữ liệu từ AppDomain

Sử dụng phương thức SetData() và GetData(), bạn có thể lưu và lấy bất kì dữ liệu nào từ một AppDomain:

public static void Main()
{
    AppDomain ad=AppDomain.CurrentDomain;

    ad.SetData("MyData", new {Name="YinYang",Age=11});
    object obj=ad.GetData("MyData");
    Console.WriteLine(obj);
        Console.Read();
}

Output:

{ Name = YinYang, Age = 11 }

Thực thi một assembly trong AppDomain

Để làm điều này, bạn dùng phương thức instance AppDomain.ExecuteAssembly() hoặc AppDomain.ExecuteAssemblyByName(). Ví dụ sau sẽ nạp assembly hiện tại (tên file là AppDomainExample.exe) vào ứng dụng,

public static void Main()
{
    Console.WriteLine("Hello AppDomain");
    AppDomain.CurrentDomain.ExecuteAssembly("AppDomainExample.exe");
    Console.Read();
}

Thực thi đoạn mã trên, ứng dụng sẽ xuất liên tục ra màn hình dòng chữ “Hello AppDomain” cho đến khi một StackOverflowException được ném ra. Nguyên nhân của lỗi này là do ứng dụng liên tục thực thi thêm một instance của chính nó trong cùng AppDomain hiện tại, việc này giống như bạn gọi các hàm đệ quy trong lập trình.

Bởi vì đây chỉ là ví dụ, trong thực tế thì ứng dụng dạng này hầu như không tồn tại. Bây giờ tôi muốn một điểm dừng để chỉ nạp 5 assembly vào AppDomain. Giải pháp của tôi là sử dụng cách lưu dữ liệu vào trong AppDomain như trong ví dụ trước:

public static void Main()
{
    AppDomain app=AppDomain.CurrentDomain;

    int count = (int)(app.GetData("count")??1);

    Console.WriteLine("Hello "+app.FriendlyName+" #"+count);

    app.SetData("count",count+1);
    if(count<10)
    {
        AppDomain.CurrentDomain.ExecuteAssembly("AppDomainExample.exe");
    }
    //else
    Console.ReadLine();
}

Output:

Hello AppDomainExample.exe #1
Hello AppDomainExample.exe #2
Hello AppDomainExample.exe #3
Hello AppDomainExample.exe #4
Hello AppDomainExample.exe #5

Như vậy trong 1 AppDomain có 5 assembly cùng hoạt động, nếu bạn xem bằng TaskManager sẽ thấy rằng chỉ có một process AppDomainExample duy nhất và dung lượng bộ nhớ sử dụng tiết kiệm rất đáng kể so với việc thực thi đồng thời 5 process cho mỗi assembly.

Tạo và hủy AppDomain

Lớp AppDomain cung cấp hai phương thức static là CreateDomain() và Unload() để tạo và hủy một AppDomain trong process hiện tại. Việc sử dụng Unload() có thể sinh ra các exception do các Thread trong AppDomain đang được sử dụng.

Ví dụ sau minh họa việc sử dụng hai phương thức này, trong đó ‘AppDomainExample.exe’ là tên của assembly hiện tại:

public static void Main()
{
    Console.WriteLine("Enter AppDomain\t\t :'{0}'",AppDomain.CurrentDomain.FriendlyName);

    AppDomain ad=(AppDomain)AppDomain.CurrentDomain.GetData("DefaultDomain");

    if(ad==null) // Default AppDomain
    {
        ad=AppDomain.CreateDomain("NewAppDomain");

        ad.DomainUnload+= delegate {
            Console.WriteLine("   Unloading\t\t :'{0}'",AppDomain.CurrentDomain.FriendlyName);
        };

        ad.SetData("DefaultDomain",AppDomain.CurrentDomain);
        ad.ExecuteAssembly("AppDomainExample.exe");

        AppDomain.Unload(ad);
        Console.WriteLine("Current AppDomain\t :'{0}'", AppDomain.CurrentDomain.FriendlyName);
        Console.Read();
    }
    else    // New AppDomain
    {
        Console.WriteLine("   Default AppDomain\t :'{0}'", ad.FriendlyName);
        Console.WriteLine("   Current AppDomain\t :'{0}'", AppDomain.CurrentDomain.FriendlyName);
    }
}

Output:

Enter AppDomain          :’AppDomainExample.exe’
Enter AppDomain          :’NewAppDomain’
Default AppDomain     :’AppDomainExample.exe’
Current AppDomain     :’NewAppDomain’
Unloading             :’NewAppDomain’
Current AppDomain        :’AppDomainExample.exe’

http://yinyangit.wordpress.com

About these ads

One thought on “.Net – Tìm hiểu về Application Domain (AppDomain)

Gửi phản hồi

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Thay đổi )

Twitter picture

You are commenting using your Twitter account. Log Out / Thay đổi )

Facebook photo

You are commenting using your Facebook account. Log Out / Thay đổi )

Google+ photo

You are commenting using your Google+ account. Log Out / Thay đổi )

Connecting to %s