cuốn sách gpt4 ai đã làm

Giải thích tổng hợp đối tượng không xâm nhập .NET

In lại Tác giả: Sahara Thời gian cập nhật: 2024-10-16 06:18:59 60 4
mua khóa gpt4 Nike

Pooling (https://github.com/inversionhourglass/Pooling), một thành phần nhóm đối tượng tại thời gian biên dịch, thay thế hoạt động mới của loại được chỉ định bằng hoạt động nhóm đối tượng tại thời điểm biên dịch, đơn giản hóa quy trình mã hóa và loại bỏ nhu cầu của nhà phát triển để viết thủ công mã hoạt động của nhóm đối tượng. Đồng thời, nó cung cấp một giải pháp hoàn toàn không xâm phạm, có thể được sử dụng như một giải pháp tối ưu hóa hiệu suất tạm thời và giải pháp tối ưu hóa hiệu suất dự án dài hạn.

bắt đầu nhanh chóng

Trích dẫn Pooling.Fody.

dotnet thêm gói Pooling.Fody.

Đảm bảo rằng Pooling đã được định cấu hình trong tệp FodyWeavers.xml. Nếu dự án hiện tại không có tệp FodyWeavers.xml, bạn có thể biên dịch dự án trực tiếp và tệp FodyWeavers.xml sẽ được tạo tự động:

   
// 1. Loại cần được gộp sẽ triển khai giao diện IPoolItem public class TestItem : IPoolItem { public int Value { get; set; // Khi đối tượng quay trở lại nhóm đối tượng, trạng thái của cá thể được đặt lại thông qua phương thức này public bool TryReset() { return true; } } // 2. Sử dụng từ khóa new ở bất cứ đâu để tạo một đối tượng kiểu này public class Test { public void M() { var Random = new Random(); ); item.Value = Random.Next(); Console.WriteLine(item.Value); } } // Mã được biên dịch public class Test { public void M() { TestItem item = null; item = Pool.Get(); item.Value = Random.Next(); Console.WriteLine(item.Value); } cuối cùng { if (item !=) null) { Pool.Return(item); } } } }

IPoolItem

Như được hiển thị trong mã ở phần khởi động nhanh, loại triển khai giao diện IPoolItem là loại gộp. Tại thời điểm biên dịch, Pooling sẽ thay thế thao tác mới của nó bằng thao tác nhóm đối tượng và trả về phiên bản đối tượng gộp cho đối tượng cuối cùng. chặn trong hồ bơi. IPoolItem chỉ có một phương thức TryReset, được sử dụng để đặt lại trạng thái khi đối tượng quay trở lại nhóm đối tượng. Khi phương thức này trả về sai, điều đó có nghĩa là việc đặt lại trạng thái không thành công và đối tượng sẽ bị loại bỏ.

PoolingĐộc quyềnThuộc tính

Theo mặc định, loại gộp triển khai IPoolItem sẽ thực hiện các hoạt động gộp trong tất cả các phương thức, nhưng đôi khi chúng ta có thể muốn loại gộp không thực hiện các thao tác gộp trong một số loại. Ví dụ: chúng ta có thể tạo một số loại Quản lý gộp hoặc loại Trình tạo. Tại thời điểm này, việc áp dụng PoolingExclusiveAttribution trên loại gộp có thể chỉ định rằng loại gộp sẽ không thực hiện các hoạt động gộp trong một số loại/phương thức nhất định.

[PoolingExclusive(Types = [typeof(TestItemBuilder)], Pattern = "execution(* TestItemManager.*(..))")] lớp công khai TestItem : IPoolItem { public bool TryReset() => true; TestItem _item chỉ đọc; riêng tư TestItemBuilder() { // Vì TestItemBuilder bị loại trừ thông qua thuộc tính Loại của PoolingExclusive, nên nó sẽ không được thay thế bằng nhóm đối tượng Operation_item = new TestItem(); } public static TestItemBuilder Create() => new TestItemBuilder(); .. trả lại cái này; } public TestItem Build() { return _item; } } public class TestItemManager { testItem riêng tư? _cacheItem; public void Thực thi() { // Vì tất cả các phương thức trong TestItemManager đều bị loại trừ thông qua thuộc tính Pattern của PoolingExclusive, hoạt động của nhóm đối tượng sẽ không được thay thế ở đây var item = _cacheItem ?? } }

Như được hiển thị trong đoạn mã trên, PoolingExclusiveAttribution có hai thuộc tính, Loại và Mẫu. Các loại là một mảng thuộc loại Loại. Loại gộp hiện tại sẽ không thực hiện các hoạt động gộp trong các phương thức của các loại trong mảng; Mẫu là một biểu thức AspectN kiểu chuỗi, có thể khớp chi tiết với các phương thức cụ thể (để biết chi tiết về định dạng biểu thức AspectN). , hãy xem: https://github.com/inversionhourglass/Shared.Cecil.AspectN/blob/master/README.md), loại gộp hiện tại sẽ không thực hiện các hoạt động gộp trong phương thức phù hợp. Hai thuộc tính có thể được sử dụng một hoặc cùng một lúc. Khi được sử dụng cùng lúc, tất cả các loại/phương thức khớp với hai thuộc tính sẽ bị loại trừ.

NonPooledThuộc tính

Như đã đề cập trước đó, bạn có thể sử dụng PoolingExclusiveAttribution để chỉ định rằng đối tượng được gộp hiện tại sẽ không được gộp trong một số loại/phương thức nhất định. Tuy nhiên, vì PoolingExclusiveAttribution cần được áp dụng trực tiếp cho loại được gộp, nếu bạn sử dụng loại được gộp trong bên thứ ba. thư viện lớp, tại thời điểm này bạn không thể áp dụng trực tiếp PoolingExclusiveAttribution cho kiểu gộp này. Đối với những trường hợp như vậy, bạn có thể sử dụng NonPooledAttribution để chỉ ra rằng phương thức hiện tại không thực hiện các hoạt động gộp.

lớp công khai TestItem1 : IPoolItem { bool công khai TryReset() => true; } lớp công khai TestItem2 : IPoolItem { bool công khai TryReset() => true; } lớp công khai TestItem3 : IPoolItem { bool TryReset() => true; Kiểm tra { [NonPooled] public void M() { // Vì phương thức này áp dụng NonPooledAttribution nên ba thao tác mới sau đây sẽ không được thay thế bằng các thao tác nhóm đối tượng var item1 = new TestItem1(); var item2 = new TestItem2();

Đôi khi bạn có thể không muốn loại trừ tất cả các kiểu gộp trong phương thức khỏi các hoạt động gộp. Trong trường hợp này, bạn có thể chỉ định các kiểu gộp không thể được gộp thông qua hai thuộc tính Loại và Mẫu của NonPooledAttribution. Các loại là một mảng kiểu Kiểu và tất cả các kiểu trong mảng không thể được gộp lại trong phương thức hiện tại; Mẫu là một biểu thức kiểu AspectN kiểu chuỗi và tất cả các kiểu khớp không thể được gộp lại trong phương thức hiện tại.

public class Test { [NonPooled(Types = [typeof(TestItem1)], Pattern = "*..TestItem3")] public void M() { // TestItem1 không được phép thực hiện các hoạt động gộp thông qua các Loại và TestItem3 không được phép được thực hiện thông qua thao tác gộp mẫu, chỉ TestItem2 mới có thể thực hiện thao tác gộp var item1 = new TestItem1(); var item2 = new TestItem2(); TestItem3();

Các biểu thức loại AspectN rất linh hoạt và có thể thay đổi, đồng thời hỗ trợ toán tử NOT logic!, vì vậy bạn có thể dễ dàng sử dụng các biểu thức loại AspectN để chỉ cho phép một loại nhất định. Ví dụ: ví dụ trên có thể được thay đổi đơn giản thành [NonPooled(Pattern = "!TestItem2" )] , để biết thêm mô tả về biểu thức AspectN, hãy xem: https://github.com/inversionhourglass/Shared.Cecil.AspectN/blob/master/README.md.

NonPooledAttribution có thể được áp dụng không chỉ ở cấp phương thức mà còn trên các loại và tập hợp. Áp dụng cho một lớp tương đương với việc áp dụng cho tất cả các phương thức của lớp (bao gồm các thuộc tính và hàm tạo), áp dụng cho một hợp ngữ tương đương với việc áp dụng cho tất cả các phương thức của hợp ngữ hiện tại (bao gồm các thuộc tính và hàm tạo), và nếu áp dụng cho một hợp ngữ Nếu các thuộc tính Loại và Mẫu không được chỉ định, nó tương đương với việc vô hiệu hóa Pooling trong cụm hiện tại.

Không có hoạt động tổng hợp xâm nhập

Đọc xong nội dung trước rồi nhìn vào tiêu đề, có thể bạn sẽ lẩm bẩm "Đây là loại phương pháp không xâm lấn gì vậy? Đây không chỉ là một tiêu đề". Bây giờ đến phần tiêu đề. Pooling cung cấp một phương thức truy cập không xâm phạm, phù hợp để tối ưu hóa hiệu suất tạm thời và chuyển đổi dự án dài hạn. Không cần triển khai giao diện IPoolItem và loại gộp có thể được chỉ định thông qua cấu hình.

Giả sử rằng bạn hiện có đoạn mã sau:

không gian tên ABC; lớp công khai Item1 { đối tượng công khai GetAndDelete() => null; } lớp công khai Item2 { public bool Clear() => true; } lớp công khai Item3 { } kiểm tra lớp công khai { public static void M1() { var item1 = new Item1(); var item2 = new Item2(); var item3 = new Item3(); {item2}, {item3}"); } public static async ValueTask M2() { var item1 = new Item1(); var item2 = new Item2(); chờ đợi Task.Yield(); var item3 = new Item3(); Console.WriteLine($"{item1}, {item2}, {item3}");

Sau khi dự án tham chiếu Pooling.Fody, một tệp FodyWeavers.xml sẽ được tạo trong thư mục dự án khi biên dịch dự án. Chúng tôi sửa đổi nút Pooling theo ví dụ sau:

        

Trong cấu hình, mỗi nút phù hợp với một loại. của họ là:

  • mẫuLoại phù hợp là loại lớn và phương thức phù hợp với trạng thái thiết lập lại phương thức (tương thích với phương thức TryReset của IPoolItem).
  • không quốc tế: AspectN kiểu biểu thức. không cần thiết lập lại thao tác.
  • thanh trà: Biểu thức AspectN.mẫukhông quốc tếKhi cấu hình này được đặt mặc định, điều đó có nghĩa phù hợp với tất cả các phương thức hiện tại của tập hợp.
  • không kiểm tra: Biểu thức AspectN.mẫukhông quốc tếKhi cấu hình này được đặt mặc định, điều đó có nghĩa là không có phương thức nào được loại trừ. cùng loại mà có thể thực hiện các hoạt động cấp tínhthanh tràSet withkhông kiểm traSự khác biệt của bộ.

Sau đó, qua cấu hình, code Test được biên dịch là:

Kiểm tra lớp công khai { public static void M1() { Item1 item1 = null; Item2 item2 = null; Item3 item3 = null;.Get();.Get(); Console.WriteLine($"{item1}, {item2}, {item3}"); cuối cùng là { if (item1 != null) { item1.GetAndDelete();.Return(item1); } if (item2 != null) { if (item2.Clear()) { Pool.Return(item2) ; } } if (item3 != null) { Nhóm.Return(item3); } } không đồng bộ công khai ValueTask M2() { Item1 item1 = null; thử { item1 = Pool.Get(); var item2 = new Item2(); đang chờ Task.Yield(); $"{item1}, {item2}, {item3}"); Nhóm .GetAndDelete();.Return(item1);

M1, item1 và item2 khác nhau trong cách gọi reset phương thức. loại giá trị trả về của việc đặt lại phương thức của Item2 là bool và Pooling sẽ cho kết quả là dù việc thiết lập lại có thành công hay không. Đối với void hoặc trả về giá trị khác của các loại, Pooling sẽ được đặt lại mặc định thành công sau khi phương thức trả về thành công công.

Tổng hợp hoạt động không xâm phạm

Bạn có bối rối khi nhìn thấy tiêu đề này không? lại muốn nghĩ ra phương pháp không xâm phạm? Sự việc khác biệt giữa chúng là gì?

Trong hoạt động xâm lược không được mô tả ở trên, chúng tôi không cần thay đổi bất kỳ mã C# nào để hoàn thành thao tác các loại đã được xác định cụ thể, nhưng chúng tôi vẫn cần bổ sung phần phụ thuộc NuGet của Pooling.Fody và sửa đổi FodyWeavers.xml cho cấu hình hình. cả? đầu vào nào dành riêng cho nhà phát triển. Cấu hình FodyWeavers.xml được dừng lại trong CI/phát hành hành động.

những lợi ích là gì

Loại tối ưu hóa tương tự như đối tượng nhóm này thường không chỉ là dự án tối ưu cần có tối ưu hóa. việc định cấu hình sẽ không có kết quả. khi đối mặt với một số dự án cổ xưa, ai đó không thể sẵn sàng thay đổi bất kỳ mã nào, ngay cả khi đó chỉ là tệp dự án và cấu hình FodyWeavers. nhiên, hoạt động sửa đổi quy trình phát hiện/CIsystem tốt nhất có thể rộng hơn. Đây chỉ là một ý tưởng không. xâm phạm.

Làm thế nào để đạt được

Cách trực tiếp nhất là bổ sung các phần phụ thuộc NuGet vào dự án thông qua gói bổ sung dotnet Pooling.Fody trong quá trình xây dựng CI hoặc trình phát hiện hành động, sau đó sao chép FodyWeavers.xml đã được cấu hình sẵn vào dự án thư mục. khác, việc ghi đè trực tiếp lên FodyWeavers.xml ban đầu có thể khiến các plug-in gốc không hợp lệ. nội dung của FodyWeavers.xml phức tạp hơn thông qua các lệnh. phần phụ thuộc NuGet và cấu hình FodyWeavers.xml trong một bước.

        

For FodyWeavers.xml ở trên, command tương thích sử dụng Cli4Fody là:

fody-cli MySolution.sln \ --addin Pooling -pv 0.1.0 \ -n Items:Item -a "pattern=ABCItem1.GetAndDelete" \ -n Items:Item -a "pattern=Item2.Clear" -a "inspect =execution(* Test.M1(..))" \ -n Mục:Mục -a "stateless=*..Item3" -a "not-inspect=method(* Test.M2())"

Ưu điểm của Cli4Fody là có thể hoàn thành tham chiếu NuGet và FodyWeavers. các plug-in khác của Fody trong FodyWeavers.xml.

Trường hợp tối ưu hóa không xâm phạm Rougamo

Rougamo, một AOP thành phần được dệt bằng mã tĩnh. GC thông tin qua các cấu hình. và chỉ có thể phát triển các giao diện. Structure. sẽ được sử dụng để trình bày cách sử dụng Cli4Fody nhằm hoàn thành hoạt động tổng hợp không xâm phạm phạm vi xây dựng Docker:

Thư mục cấu hình:

├── Lib │ └── Lib.csproj # Phụ thuộc vào Rougamo.Fody │ └── TestAttribution.cs # Kế thừa MoAttribution └── RougamoPoolingConsoleApp └── BenchmarkTest.cs └── Dockerfile └── RougamoPoolingConsoleApp.csproj # Tham khảo Lib.csproj, không có bất kỳ phần bổ trợ phụ thuộc nào Fody nào └── Program.cs

BenchmarkTest.cs và TestAttribution được áp dụng cho cả hai phương thức Formula. cấu hình TestAttribution làm loại côn trùng. so sánh M và N thông tin qua vấn đề GC.

// Lớp công khai TestAttribution TestAttribution : MoAttribution { // Để làm cho GC hiệu ứng rõ ràng hơn, mỗi TestAttribution sẽ chứa một mảng byte có độ dài chỉ 1024 byte đọc riêng tư[] _occupy = byte mới [1024] } // Lớp công khai BenchmarkTest; BenchmarkTest { [Điểm chuẩn] [Kiểm tra] public void M() { } [Điểm chuẩn] [Kiểm tra] public void N() { } } // Chương trình var config = ManualConfig.Create(DefaultConfig.Instance) .AddDiagnoser(MemoryDiagnoser.Default);(cấu hình);

Dockerfile.

TỪ mcr.microsoft.com/dotnet/sdk:8.0 WORKDIR /src COPY . ENV PATH="$PATH:/root/.dotnet/tools" RUN cài đặt công cụ dotnet -g Cli4Fody RUN fody-cli DockerSample.sln -- addin Rougamo -pv 4.0.4 --addin Pooling -pv 0.1.0 -n Items:Item -a "stateless=Rougamo.IMo+" -a "inspect=method(* RougamoPoolingConsoleApp.BenchmarkTest.M(..))" RUN dotnet Khôi phục RUN dotnet Publish "./RougamoPoolingConsoleApp/ RougamoPoolingConsoleApp.csproj" -c Phát hành - o /src/bin/xuất bản WORKDIR /src/bin/xuất bản ENTRYPOINT ["dotnet", "RougamoPoolingConsoleApp.dll"]

BenchmarkTest.M đã được thu gọn lại, nhưng TestAttribution được kết hợp với BenchmarkTest.N không được reload.

| Phương pháp | Trung bình | Lỗi Gen0 - ----:|-------:|-------:|----------:| 4,09 ns |

Mã mẫu được chỉnh sửa được lưu tại: https://github.com/inversionhourglass/Pooling/tree/master/samples/DockerSample.

Trong ví dụ này, quá trình tối ưu hóa nhóm đối tượng của Rougamo được hoàn thành bằng cách sử dụng Cli4Fody trong bước xây dựng Docker. Toàn bộ quá trình này hoàn toàn không bị xâm phạm trong quá trình phát triển. Nếu bạn dự định sử dụng phương pháp này để tối ưu hóa nhóm đối tượng của Rougamo, cần lưu ý rằng loại khía cạnh TestAttribution trong ví dụ hiện tại là không trạng thái, vì vậy bạn cần xác nhận với sự phát triển rằng tất cả các loại khía cạnh được xác định đều không trạng thái. , bạn cần xác định phương thức đặt lại và sử dụng thuộc tính mẫu thay vì thuộc tính không trạng thái khi xác định nút Mục.

Có một điều khác mà bạn có thể không nhận thấy trong ví dụ này. Chỉ dự án Lib tham chiếu đến Rougamo.Fody và dự án RougamoPoolingConsoleApp không tham chiếu đến Rougamo.Fody. Theo mặc định, TestAttribution được áp dụng cho BenchmarkTest sẽ không có hiệu lực, nhưng trong ví dụ của tôi. Nhưng nó đã có hiệu lực. Điều này là do các tham số liên quan của Rougamo cũng được chỉ định khi sử dụng Cli4Fody sẽ thêm tham chiếu Rougamo.Fody vào RougamoPoolingConsoleApp, do đó, Cli4Fody cũng có thể được sử dụng để tránh thiếu sự phụ thuộc trực tiếp vào plug-in Fody của nhóm dự án. trên Cli4Fody, xem: https://github.com/inversionhourglass/Cli4Fody.

Các mục cấu hình

Cấu hình nút Item được giới thiệu trong hoạt động gộp không xâm nhập. Ngoài mục cấu hình Item Pooling còn cung cấp các mục cấu hình khác Sau đây là một ví dụ cấu hình hoàn chỉnh:

  any_aspectn_pattern any_aspectn_pattern   any_aspectn_pattern < NotInspect>any_aspectn_pattern      
đường dẫn nút Tên tài sản sử dụng
/Tập hợp đã bật Có bật tính năng gộp chung hay không
/Tập hợp khả năng truy cập tổng hợp Liệu AspectN có sử dụng khả năng truy cập kết hợp lớp + phương thức để khớp hay không. Theo mặc định, việc so khớp chỉ dựa trên khả năng truy cập của phương thức. Ví dụ: nếu khả năng truy cập của một lớp là nội bộ và khả năng truy cập của một phương thức là công khai thì khả năng truy cập của phương thức đó được coi là công khai theo mặc định. khả năng tiếp cận của phương thức là công khai. Khả năng tiếp cận của phương thức được coi là nội bộ.
/Tập hợp/Kiểm tra/Kiểm tra [giá trị nút] Biểu thức AspectN.
Bộ lọc chung, chỉ các phương thức khớp với biểu thức này mới kiểm tra xem loại gộp có được sử dụng nội bộ hay không và thực hiện thay thế thao tác gộp. Kể cả khi nó được thực hiệnIPoolItemKiểu gộp cũng sẽ bị giới hạn bởi cấu hình này.
Nút này có thể được cấu hình với nhiều cấu hình và bộ phương thức khớp là sự kết hợp của nhiều cấu hình.
Theo mặc định, nút này có nghĩa là khớp tất cả các phương thức của tập hợp hiện tại.
Tập phương thức cuối cùng là tập phù hợp với cấu hình nút với /Gộp chung/Không kiểm tra Định cấu hình tập hợp khác biệt của các bộ phù hợp.
/Pooling/NotInspects/NotInspect [giá trị nút] Biểu thức AspectN.
Bộ lọc chung, các phương thức khớp với biểu thức này sẽ không được thay thế bằng các hoạt động gộp. Kể cả khi nó được thực hiệnIPoolItemKiểu gộp cũng sẽ bị giới hạn bởi cấu hình này.
Nút này có thể được cấu hình với nhiều cấu hình và bộ phương thức khớp là sự kết hợp của nhiều cấu hình.
Theo mặc định, nút này có nghĩa là không có phương thức nào bị loại trừ.
Bộ phương thức cuối cùng là /Tập hợp/Kiểm tra Sự khác biệt giữa tập hợp cấu hình phù hợp và tập hợp cấu hình phù hợp của nút này.
/Tập hợp/Vật phẩm/Vật phẩm mẫu AspectN Type + phương thức tên biểu thức.
Loại sẽ được sử dụng làm loại phù hợp và phương pháp phù hợp sẽ được sử dụng để thiết lập phương thức lại.
Phương thức đặt lại phải là phương thức không được tham số nếu loại giá trị trả về của phương thức là.bool, giá trị trả về cũng sẽ được sử dụng làm cơ sở cho công việc thiết lập lại thành công hay không.
Tính chất này giống nhưkhông quốc tếChỉ có thể chọn một trong hai thuộc tính.
/Tập hợp/Vật phẩm/Vật phẩm không quốc tế AspectN kiểu biểu thức.
type match sẽ được sử dụng làm loại virus, đây là loại trạng thái không cần thiết và không cần thiết lập lại trước đó quay lại đối tượng nhóm.
Tính chất này giống nhưmẫuChỉ có sẵn một lựa chọn.
/Tập hợp/Vật phẩm/Vật phẩm thanh trà Biểu thức AspectN.
mẫukhông quốc tếHợp nhất nhóm loại sẽ chỉ thực hiện các hoạt động trong phương pháp phù hợp với biểu thức.
Khi cấu hình này được đặt mặc định, điều đó có nghĩa là khớp với tất cả các phương thức của tập hợp hiện tại.
Cuối cùng, tập hợp các phương thức có thể được áp dụng cho hiện tại là một tập hợp các phương thức phù hợp hợp lý cấu hình vàkhông kiểm traĐịnh cấu hình tập hợp khác nhau của các phương thức phù hợp.
/Tập hợp/Vật phẩm/Vật phẩm không kiểm tra Biểu thức AspectN.
mẫukhông quốc tếHợp nhất loại sẽ không thực hiện các hoạt động mạnh trong phương pháp phù hợp với biểu thức này.
Khi cấu hình này được đặt mặc định, điều đó có nghĩa là không có loại phương thức nào được loại trừ.
Cuối cùng, các phương thức hợp nhất có thể được áp dụng cho hiện tại nhóm loạithanh tràSự khác biệt giữa tập hợp các phương thức phù hợp với cấu hình và tập hợp các phương thức phù hợp với cấu hình này.

Bạn có thể thấy rằng các AspectN biểu thức được sử dụng rộng rãi trong cấu hình. Để tìm hiểu thêm về cách sử dụng. AspectN biểu thức, vui lòng xem: https://github.com/inversionhourglass/Shared.Cecil.AspectN/blob/master/README.md.

Một điều cần lưu ý nữa là tất cả các phương thức trong hợp ngữ đều giống như bộ nhớ và AspectN giống như con trỏ Bạn cần cẩn thận khi vận hành bộ nhớ thông qua con trỏ. một phiên bản đối tượng được sử dụng đồng thời, vì vậy hãy thử sử dụng chính xác phù hợp khi sử dụng AspectN biểu thức và tránh sử dụng Blur match.

Cấu hình đối tượng nhóm

Tối đa số lượng đối tượng được quản lý bởi đối tượng nhóm

Tối đa số lượng đối tượng được nhóm đối tượng của mỗi loại là số lượng nhân xử lý logic với 2Environment.ProcessorCount * 2. Có hai cách để sửa đổi cài đặt mặc định này.

  1. Được chỉ định bởi mã hóa.

    Pool.GenericMaximumNội dung được giữ lại biểu tượng của tất cả các loại côn trùng và Pool.Nội dung được giữ lại tối đa biểu tượng của loại đã được xác định rõ ràng . Cái sau có mức độ ưu tiên cao hơn cái trước đó.

  2. Được định nghĩa chỉ thông qua các trường môi trường.

    Việc chỉ định môi trường biến khi khởi động ứng dụng có thể sửa đổi số lượng đối tượng tối đa NET_POOLING_MAX_RETAIN được sử dụng để đặt số lượng đối tượng Đối số Tối đa các biểu tượng được giữ trong nhóm đối tượng, trong đó {PoolItemFullName} là tên đầy đủ của các loại được độc quyền (tên namespace.class). NET_POOLING_MAX_RETAIN_System_Text_StringBuilder. môi trường biến có mức độ ưu tiên cao hơn mã đặc tả. linh hoạt hơn.

Tùy chỉnh đối tượng nhóm

Chúng tôi biết rằng có một thư viện lớp nhóm biểu tượng chính thức Microsoft.Extensions.ObjectPool. và select IL If lớp thư viện thứ ba được tham chiếu và biểu thức chữ MethodNotFoundException có thể được xử lý trong thời gian chạy, vì vậy việc giảm thiểu sự phụ thuộc của thứ ba là lựa chọn tốt nhất cho các thành phần trong thời gian biên dịch .

Một số bạn có thể lo lắng về hiệu suất của việc xây dựng đối tượng nhóm. khai báo Pooling nhóm đối tượng được sao chép từ Microsoft.Extensions.ObjectPool. hợp lý. lý do hợp lý nhất của nhóm đối tượng. phát triển giao diện IPool để xác định nhóm đối tượng chung và phát triển giao diện IPool Sau đây là minh họa đơn giản về cách thay đổi cách phát triển khai nhóm đối tượng thành Microsoft.Extensions.ObjectPool thông qua tùy chỉnh đối tượng nhóm:

// Nhóm đối tượng chung lớp khai báo MicrosoftPool : IPool { dành riêng tư tĩnh đọc ConcurrentDictionary _Pools = []; công khai T Nhận() trong đó T : class, new() { return GetPool().Get(); } public void Return(Giá trị T) trong đó T : class, new() { GetPool().Return(value); } riêng ObjectPool GetPool() trong đó T : class, new() { return (ObjectPool)_Pools.GetOrAdd(typeof(T), t => { var Provider = new DefaultObjectPoolProvider(); var Policy = new DefaultPooledObjectPolicy(); return nhà cung cấp.Create(policy); } } // Loại nhóm đối tượng có thể Lớp khai báo Cụ thể MicrosoftPool :IPool trong đó T : class, new() { riêng tư đọc ObjectPool _pool; public Cụ thểMicrosoftPool() { var nhà cung cấp = new DefaultObjectPoolProvider(); _pool = nhà cung cấp.Tạo (chính sách); } public T Get() { return _pool.Get() } public void Return(T value) ) { _pool.Return(giá trị); } } // Tốt nhất nên hoàn thành thao tác thay thế trực tiếp tại Lối vào chính Sau khi sử dụng nhóm đối tượng, thao tác thay thế sẽ không chạy // Thay thế nhóm đối tượng chung khai báo Pool.Set( new MicrosoftPool()); // Thay thế nhóm đối tượng cụ thể Pool..Set(Cụ thể mới của MicrosoftPool());

Not only a group object

Mặc dù mục tiêu của Pooling là đơn giản hóa các hoạt động của đối tượng nhóm cũng như chuyển đổi và mức độ ưu tiên hóa dự án không xâm phạm, nhưng giúp phát triển việc khai báo tổng hợp và cung cấp các tùy chọn điều chỉnh nhóm đối tượng có chức năng, bạn có thể sử dụng sử dụng Pooling để thực hiện nhiều công việc hơn là chỉ phát triển nhóm đối tượng để xây dựng một chuyến thăm quan trong đó Tất cả các phương thức xây dựng đều không có đối số được gọi.

Singleton

//Xác định nhóm đối tượng singleton public class SingletonPool :IPool trong đó T : class, new() { riêng tư chỉ đọc T _value = new(); public T Get() => _value public void Return(T value) ) { } } // Thay thế việc khai triển nhóm đối tượng Pool< >>.Set(SingletonPool mới<>>()); // Qua cấu hình thông tin, set ConcurrentDictionary thành loại loại // 

Từ điển đồng thời> chia sẻ một phiên bản.

điều khiển ngữ nghĩa

//Xác định nhóm semaphore đối tượng public class SemaphorePool :IPool trong đó T : class, new() { riêng tư đọc Semaphore _semaphore = new(3, 3); riêng tư đọc DefaultPool _pool = new() ; public T Get() { if (!_semaphore.WaitOne(100)) return null; return _pool.Get() } public void Return(T; value) { _pool.Return(value); Release(); } } // Thay thế việc phát triển khai nhóm biểu tượng Pool.Set(SemaphorePool mới()); Nhập // 

Trong ví dụ này, semaphore đối tượng nhóm được sử dụng để kiểm soát số lượng kết nối, rất phù hợp với một số vấn đề hiện tại bị giới hạn.

Đơn chủ đề

// :IPool trong đó T : class, new() { riêng tư đọc ThreadLocal _random = new(() => new()); T Get () => _random.Value!; public void Return(T value) { } } // Thay thế việc phát triển nhóm đối tượng Pool.Set(ThreadLocalPool mới()); // Đặt kết nối thành cấu hình thông tin kiểu // 

Khi bạn muốn giảm sức mạnh GC thông qua một singleton nhưng đối tượng không an toàn cho luồng, bạn có thể phát triển một nội dung singleton bằng cách sử dụng ThreadLocal.

khởi tạo tiện ích bổ sung

// Lớp công khai ServiceSetupPool : IPool { public Service1 Get() { var service1 = new Service1(); var service2 = PinnedScope.ScopedServices?.GetService(); service1.Service2 = service2; return service1 } public void Return(Service1 value) { } } // Xác định kiểu public class Service2 { } [PoolingExclusive(Types = [typeof(ServiceSetupPool)])] public class Service1 : IPoolItem { public Service2? Service2 { get; } public bool TryReset() => true; // Thay thế việc phát triển nhóm đối tượng Pool . Set(ServiceSetupPool() mới);

Trong ví dụ này, Pooling được sử dụng kết hợp với DependencyInjection.StaticAccessor để hoàn thành việc chèn các thuộc tính khác có thể được hoàn thành theo cách tương tự.

Sử dụng trí tưởng tượng của bạn

Các ví dụ trước có thể không phải là thiết bị cần thiết nhất. người phát triển ý tưởng, hiểu nguyên tắc phát triển khai cơ sở của Pooling, đó là cơ sở hoạt động mới của các tạm thời biến thể Có thể Hiện tại bạn không thể sử dụng Pooling, nhưng trong một kịch bản nhu cầu định nghĩa nhất trong tương lai, bạn có thể sử dụng Pooling để phát triển nhanh chóng mà không cần phải thay đổi nhiều mã.

Những điều cần lưu ý

  1. Không thực hiện các thao tác khởi tạo tái sử dụng trong các hàm tạo của loại côn trùng.

    Đối tượng được thu thập từ đối tượng nhóm có thể là đối tượng được sử dụng lại. được sử dụng lại sẽ không thực thi lại phương thức xây dựng, vì vậy nếu bạn có một số thao tác khởi động vào một phương thức và gọi it after thao tác mới và không được cài đặt trong hàm tạo.

    //Sửa đổi định nghĩa đối tượng lớp công khai Kết nối: IPoolItem { riêng tư đọc Socket _socket public Connection() { _socket = mới(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); } public bool TryReset() { _socket.Disconnect(true); return true; } } // Use var Connection = new Connection(); // Đã sửa đổi định nghĩa đối tượng lớp chung Kết nối: IPoolItem { riêng tư chỉ đọc Ổ cắm _socket public Connection() { _socket = new(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp } public void Connect() { _socket.Connect("127.0.0.1); ", 8888); } public void Write(string message) { // ... } public bool TryReset() { _socket.Disconnect(true); return true; } } // Sau khi sửa đổi, object use var Connection = Kết nối mới(); kết nối.Connect(); kết nối.Write("tintin");
    
  2. Chỉ hỗ trợ thay thế hoạt động mới của chức năng tạo không tham số bằng đối tượng nhóm hoạt động.

    VS nghĩa đối với một đối tượng. Bạn có thể tạo một phương thức khởi động mới để nhận các tham số này và hoàn thành việc tạo hoặc nhận các tham số tham số này thông qua các thuộc tính.

    Trong quá trình biên dịch, Pooling sẽ kiểm tra xem thao tác mới có gọi hàm tạo không tham số hay không. Nếu hàm tạo được tham số hóa được gọi, thao tác mới sẽ không được thay thế bằng thao tác nhóm đối tượng.

  3. Hãy cẩn thận để không tiếp tục tồn tại các trường hợp loại gộp.

    Hoạt động của nhóm đối tượng gộp ở cấp phương thức, nghĩa là đối tượng được gộp được tạo trong phương thức hiện tại và được giải phóng ở cuối phương thức hiện tại không thể tiếp tục tồn tại trong một trường, nếu không sẽ có nguy cơ xảy ra đồng thời. sử dụng. Nếu thời gian tồn tại của một đối tượng gộp trải dài trên nhiều phương thức thì bạn nên tạo nhóm đối tượng theo cách thủ công và quản lý đối tượng theo cách thủ công.

    Việc gộp nhóm sẽ thực hiện kiểm tra tính bền vững đơn giản trong quá trình biên dịch và các đối tượng được gộp chung sẽ không được gộp lại. Tuy nhiên, cần lưu ý rằng loại khắc phục sự cố này chỉ có thể khắc phục sự cố một số thao tác liên tục đơn giản và không thể khắc phục sự cố các hoạt động liên tục trong các tình huống phức tạp. Ví dụ: bạn gọi một phương thức khác trong phương thức hiện tại và chuyển vào một phiên bản đối tượng gộp, sau đó vào. Hoạt động kiên trì được thực hiện trong phương thức được gọi. Vì vậy về cơ bản bạn vẫn cần chú ý tránh trường hợp các đối tượng gộp lại tồn tại.

  4. Các tập hợp cần được thay thế bằng các hoạt động nhóm đối tượng tại thời điểm biên dịch cần tham chiếu Pooling.Fody.

    Nguyên tắc của Pooling là kiểm tra MSIL của tất cả các phương thức (bạn cũng có thể chọn một số phương thức thông qua cấu hình) tại thời điểm biên dịch, kiểm tra tất cả các hoạt động newobj để hoàn thành hoạt động thay thế nhóm đối tượng và kích hoạt hoạt động này bằng cách thêm tác vụ MSBuild thông qua Fody, và chỉ chương trình hiện tại Bộ tham chiếu trực tiếp Fody để hoàn thành thao tác thêm các tác vụ MSBuild. Thông qua một số cấu hình, Pooling.Fody cũng có thể tham khảo trực tiếp Pooling.Fody để hoàn thành thao tác thêm tác vụ MSBuild.

  5. Những điều cần lưu ý khi sử dụng nhiều plug-in Fody cùng lúc.

    Khi dự án tham chiếu đến plug-in Fody, tệp FodyWeavers.xml sẽ được tạo tự động trong quá trình biên dịch. Nếu tệp FodyWeavers.xml đã tồn tại và một plug-in Fody khác được tham chiếu, thì plug-in mới sẽ không được biên dịch lại. Được thêm vào tệp FodyWeavers.xml, cần phải cấu hình thủ công. Đồng thời, khi tham khảo nhiều plug-in Fody, bạn cần chú ý đến thứ tự của chúng trong FodyWeavers.xml. Thứ tự của FodyWeavers.xml tương ứng với thứ tự thực thi plug-in Một số plug-in Fody có thể có chức năng chồng chéo. và các thứ tự khác nhau có thể tạo ra các hiệu ứng khác nhau.

Khía cạnhN

Hãy để tôi đề cập đến AspectN ở cuối bài viết. Trước đây nó được gọi là biểu thức AspectJ-Like, bởi vì nó thực sự được thiết kế dựa trên định dạng của biểu thức AspectJ. Tuy nhiên, hiện tại, nó không còn là một lựa chọn nữa. nó được đổi tên thành biểu thức AspectN theo quy ước (tìm kiếm sau một thời gian, trong .NET không có thuật ngữ như vậy nên sẽ không có xung đột). AspectN lần đầu tiên có nguồn gốc từ Roujiamo 2.0 để cung cấp khả năng khớp điểm vào chính xác hơn và hiện được sử dụng lại trong Pooling.

Khi sử dụng Fody hoặc trực tiếp sử dụng Mono.Cecil để phát triển các plug-in tác vụ MSBuild, việc tìm ra các loại hoặc phương thức cần sửa đổi luôn được ưu tiên hàng đầu. Phương pháp được sử dụng phổ biến nhất là định vị thông qua siêu dữ liệu Thuộc tính về các loại và phương thức, nhưng về cơ bản, điều này xác định rằng mã phải được sửa đổi để thêm các ứng dụng Thuộc tính, điều này mang tính xâm phạm. AspectN cung cấp một cơ chế so khớp phương thức và loại không xâm phạm. Thông tin vô hạn mà các chuỗi có thể mang theo mang lại cho AspectN khả năng vô hạn để so khớp được tinh chỉnh. Nhiều plug-in Fody có thể sử dụng AspectN để đạt được việc dệt mã không xâm phạm, chẳng hạn như configureAwait.Fody có thể sử dụng AspectN để chỉ định loại hoặc phương thức nào cần áp dụng configureAwait thông qua cấu hình và loại nào không.

AspectN không phụ thuộc vào Fody, chỉ Mono.Cecil. Nếu bạn đang sử dụng Fody hoặc Mono.Cecil, bạn có thể muốn dùng thử AspectN (https://github.com/inversionhourglass/Shared.Cecil.AspectN). AspectN là một Dự án được chia sẻ không phát hành NuGet và không phụ thuộc vào phiên bản cụ thể của Mono.Cecil. Để sử dụng AspectN, bạn cần sao chép cục bộ AspectN dưới dạng một dự án được chia sẻ để tham khảo trực tiếp. được khuyến nghị Thêm AspectN làm mô hình con vào kho lưu trữ của bạn (xem Rougamo và Pooling).

Cuối cùng, bài viết này về giải pháp nhóm đối tượng không xâm nhập .NET kết thúc ở đây. Nếu bạn muốn biết thêm về giải pháp nhóm đối tượng không xâm nhập .NET, vui lòng tìm kiếm các bài viết về CFSDN hoặc tiếp tục duyệt qua các bài viết liên quan. ủng hộ blog của tôi trong tương lai! .

60 4 0
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress