Saat bermigrasi dari 
.NET Framework ke 
.NET Core , beberapa momen tidak menyenangkan mungkin muncul. Misalnya, jika aplikasi Anda menggunakan domain, Anda harus menulis ulang logikanya. Situasi yang serupa dengan 
Thread.Abort () : 
Microsoft sangat 
tidak disukai oleh praktik ini (dan memang demikian) bahwa mereka pertama kali menyatakan metode ini 
sudah usang , dan kemudian benar-benar memotongnya keluar dari kerangka kerja dan sekarang dengan berbahaya melempar 
PlatformNotSupportedException .
Tetapi bagaimana jika aplikasi Anda menggunakan 
Thread.Abort () , dan Anda 
benar - 
benar ingin menerjemahkannya ke 
.NET Core tanpa menulis ulang apa pun? Yah, kami tahu betul bahwa platform bahkan mendukung fungsi ini, jadi saya bisa menyenangkan Anda: ada jalan keluar, Anda hanya perlu merakit versi 
CLR Anda sendiri.
Penafian: Ini adalah artikel yang sepenuhnya praktis dengan teori minimum, yang dirancang hanya untuk menunjukkan pilihan baru untuk interaksi antara pengembang dan lingkungan .NET. Jangan pernah melakukan ini dalam produksi. Tetapi jika Anda benar-benar ingin ...
Ini dimungkinkan berkat dua hal: keinginan 
Microsoft untuk cross-platform 
.NET Core dan pekerjaan yang dilakukan oleh pengembang untuk mentransfer kode sumber kerangka kerja untuk membuka akses. Mari manfaatkan ini.
Minimum teoritis:
- mempublikasikan dotnet memungkinkan kita untuk mempublikasikan aplikasi mandiri : kerangka kerja akan dikirimkan bersamanya, dan tidak mencari di suatu tempat di GAC
- Versi CoreCLR di mana aplikasi akan berjalan, dalam kondisi tertentu, dapat diatur menggunakan runtimeconfig.json
- Kita dapat membangun CoreFX kita sendiri: github.com/dotnet/corefx
- Kita dapat membangun CoreCLR kita sendiri: github.com/dotnet/coreclr
Kustomisasi CoreFX
Sebelum beralih ke tujuan utama kami - mengembalikan 
Thread.Abort ( ) - mari kita ubah sesuatu yang mendasar di 
CoreFX untuk 
pemanasan untuk menguji fungsionalitas semua alat. Sebagai contoh, dalam jejak artikel saya 
sebelumnya tentang 
dinamis , kami sepenuhnya melarang penggunaannya dalam aplikasi. Mengapa Karena kita bisa.
Prasyarat
Pertama-tama, kami akan menginstal 
semua yang diperlukan untuk perakitan:
- CMake
- Visual Studio 2019 Pratinjau
- .NET Core SDK terbaru (.NET Core 3.0 Preview)
Visual Studio 2019 - Beban Kerja
Pengembangan desktop .NET- Semua Komponen yang Diperlukan
- .NET Framework 4.7.2 Alat Pengembangan
Pengembangan desktop dengan C ++- Semua Komponen yang Diperlukan
- Toolset VC ++ 2019 v142 (x86, x64)
- Windows 8.1 SDK dan UCRT SDK
- Toolset VC ++ 2017 v141 (x86, x64)
.NET Core pengembangan lintas platform- Semua Komponen yang Diperlukan
Visual Studio 2019 - Komponen individual
- C # dan Visual Basic Roslyn Compiler
- Alat Analisis Statis
- .NET Portable Library Targeting Pack
- Windows 10 SDK atau Windows 8.1 SDK
- Visual Studio C ++ Fitur Inti
- Toolset VC ++ 2019 v142 (x86, x64)
- Toolset VC ++ 2017 v141 (x86, x64)
- Msbuild
- .NET Framework 4.7.2 Paket Penargetan
- Windows Universal CRT SDK
Klon corefx :
git clone https://github.com/dotnet/corefx.git 
Sekarang nonaktifkan 
dinamis . Kami akan terbuka untuk ini (selanjutnya saya akan menunjukkan jalur relatif ke akar repositori)
 corefx\src\System.Linq.Expressions\src\System\Runtime\CompilerServices\CallSite.cs 
Dan di akhir fungsi 
CallSite <T> 
.Create, masukkan kode biasa:
 throw new PlatformNotSupportedException("No way"); 
Kami kembali ke 
corefx dan menjalankan 
build.cmd . Setelah perakitan selesai, buat proyek 
.NET Core baru di 
Visual Studio dengan konten berikut:
 public int Test { get; set; } public static void Main(string[] args) { try { dynamic a = new Program(); a.Test = 120; } catch (Exception e) { Console.WriteLine(e); }  
Kami menyusun proyek kami. Sekarang pergilah ke
 corefx\artifacts\packages\Debug\NonShipping 
dan kami menemukan ada paket yang terlihat seperti ini: 
Microsoft.Private.CoreFx.NETCoreApp. 5.0.0-dev.19465.1 .nupkg . Kami membuka 
.csproj proyek kami dan menyisipkan baris berikut di sana:
 <PropertyGroup> <PackageConflictPreferredPackages>Microsoft.Private.CoreFx.NETCoreApp;runtime.$(RuntimeIdentifiers).Microsoft.Private.CoreFx.NETCoreApp;$(PackageConflictPreferredPackages)</PackageConflictPreferredPackages> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Private.CoreFx.NETCoreApp" Version="5.0.0-dev.19465.1" /> </ItemGroup> 
Versi harus sama dengan nama paket yang dirakit. Dalam kasus saya, 
5.0.0-dev.19465.1 .

Buka pengaturan 
nuget untuk proyek kami dan tambahkan dua jalur baru di sana:
 corefx\artifacts\packages\Debug\NonShipping corefx\artifacts\packages\Debug\Shipping 
Dan hapus centang semua yang lain.

Buka folder proyek dan jalankan
 dotnet publish --runtime win-x64 --self-contained 
Selesai! Tetap berjalan:

Itu berhasil! Perpustakaan tidak diambil dari 
GAC , 
dinamis tidak berfungsi.
Buat CoreCLR Hebat Lagi
Sekarang mari kita beralih ke bagian kedua, mengembalikan 
Thread.Abort () . Kejutan yang tidak menyenangkan menunggu kita di sini: Implementasi 
utas terletak pada 
CoreCLR , yang bukan bagian dari 
CoreFX dan sudah diinstal sebelumnya pada mesin secara terpisah. Pertama, buat proyek demo:
 var runtimeInformation = RuntimeInformation.FrameworkDescription; Console.WriteLine(runtimeInformation); var thr = new Thread(() => { try { while (true) { Console.WriteLine("."); Thread.Sleep(500); } } catch (ThreadAbortException) { Console.WriteLine("Thread aborted!"); } }); foreach (var asm in AppDomain.CurrentDomain.GetAssemblies()) { Console.WriteLine(asm.Location); } thr.Start(); Thread.Sleep(2000); thr.Abort(); 
Mengempiskan coreclr . Temukan file
 coreclr\src\System.Private.CoreLib\shared\System\Threading\Thread.cs 
Dan ganti 
Abort () dengan
 [SecuritySafeCritical] [SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)] public void Abort() { AbortInternal(); } [System.Security.SecurityCritical]  
Sekarang kita perlu mengembalikan atribut dan implementasi 
c ++ . Saya mengumpulkannya dalam beberapa bagian dari berbagai repositori terbuka 
.NET Framework dan untuk kenyamanan saya merancang semua perubahan dalam bentuk 
permintaan tarik .
Catatan: saat membangun, ada masalah dengan sumber daya di atribut "baru", yang saya 
"Tetap" dengan colokan. Ingatlah hal ini jika Anda ingin menggunakan kode ini di mana pun selain eksperimen di rumah.Setelah mengintegrasikan perubahan ini ke dalam kode, jalankan 
build.cmd dari 
coreclr . Perakitan pada tahap selanjutnya mungkin mulai menaburkan kesalahan, tapi itu tidak menakutkan, hal utama bagi kami adalah bahwa 
CoreCLR dapat berkumpul. Itu akan terletak di:
 coreclr\bin\Product\Windows_NT.x64.Debug 
Cara mudah
Kami melakukan
 dotnet publish --runtime win-x64 --self-contained 
File dari 
Windows_NT.x64.Debug dijatuhkan ke folder dengan aplikasi yang diterbitkan.
Cara yang sulit
Setelah perpustakaan dirakit, buka
 C:\Program Files\dotnet\shared\Microsoft.NETCore.App 
dan mengkloning folder 3.0.0. Kami akan menyebutnya, misalnya, 5.0.1. Kami menyalin semua yang ada di 
Windows_NT.x64.Debug , kecuali foldernya. Sekarang versi 
CoreCLR kami akan tersedia melalui runtimeconfig.
Menyatukan proyek kami. Tambahkan ke 
.csproj :
 <PropertyGroup> <DisableImplicitFrameworkReferences>true</DisableImplicitFrameworkReferences> <PackageConflictPreferredPackages>Microsoft.Private.CoreFx.NETCoreApp;runtime.$(RuntimeIdentifiers).Microsoft.Private.CoreFx.NETCoreApp;$(PackageConflictPreferredPackages)</PackageConflictPreferredPackages> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.Private.CoreFx.NETCoreApp" Version="5.0.0-dev.19465.1" /> </ItemGroup> 
Kami mengulangi manipulasi dengan 
nuget dari bagian artikel sebelumnya. Terbitkan
 dotnet publish --runtime win-x64 --self-contained 
Di 
runtimeconfig.json, masukkan konfigurasi berikut:
 { "runtimeOptions": { "tfm": "netcoreapp3.0", "framework": { "name": "Microsoft.NETCore.App", "version": "5.0.1" } } } 
Hasil
Luncurkan!

Keajaiban itu terjadi. Sekarang di aplikasi 
.NET Core kami 
Thread.Abort () berjalan kembali. Tapi, tentu saja, hanya di 
Windows .