<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Performance | The .NET Blog</title><link>https://thedotnetblog.com/ar/tags/performance/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>ar</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Tue, 26 May 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/ar/tags/performance/index.xml" rel="self" type="application/rss+xml"/><item><title>‎.NET 11 يصلح أخيرًا واجهة برمجة تطبيقات العمليات</title><link>https://thedotnetblog.com/ar/news/emiliano-montesdeoca/dotnet-11-process-api-improvements-runandcapturetext/</link><pubDate>Tue, 26 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ar/news/emiliano-montesdeoca/dotnet-11-process-api-improvements-runandcapturetext/</guid><description>‎System.Diagnostics.Process يحصل على أكبر تحديث له منذ سنوات. ‎RunAndCaptureTextAsync وKillOnParentExit وواجهات SafeProcessHandle API والتحكم الكامل في إعادة توجيه المقابض القياسية — لا مزيد من الكود النمطي للتعامل مع الإغلاق الميت.</description><content:encoded>&lt;p&gt;كل مطور .NET احتاج إلى إطلاق عملية والتقاط مخرجاتها قد كتب نوعًا من الكود النمطي الخطير نفسه: قراءة غير متزامنة من stdout، وقراءة غير متزامنة من stderr، و&lt;code&gt;WaitForExitAsync&lt;/code&gt;، مع عدم نسيان إفراغ كلا التيارين وإلا ستواجه إغلاقًا ميتًا. إنه فخ معروف موجود منذ سنوات.&lt;/p&gt;
&lt;p&gt;‎.NET 11 يصلح هذا أخيرًا بشكل صحيح.&lt;/p&gt;
&lt;h2 id="runandcapturetextasync"&gt;RunAndCaptureTextAsync&lt;/h2&gt;
&lt;p&gt;الإضافة الرئيسية: طريقة ثابتة واحدة تبدأ عملية، وتلتقط stdout وstderr، وتنتظر الإنهاء دون إغلاق ميت.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAndCaptureTextAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;--version&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;StandardOutput&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;استدعاء واحد. لا إفراغ يدوي للتيارات. لا &lt;code&gt;WaitForExit&lt;/code&gt; موضوع بعناية. إذا كنت تحتاج فقط إلى تشغيل شيء ما والحصول على مخرجاته، فهذه هي واجهة برمجة التطبيقات التي تريدها.&lt;/p&gt;
&lt;p&gt;هناك أيضًا &lt;code&gt;Process.RunAsync&lt;/code&gt; للحالة التي تريد فيها الانتظار حتى الإنهاء دون التقاط المخرجات.&lt;/p&gt;
&lt;h2 id="killonparentexit"&gt;KillOnParentExit&lt;/h2&gt;
&lt;p&gt;مشكلة شائعة مع العمليات المُطلقة: إذا تعطل الوالد أو أُنهي، تستمر العمليات الفرعية في التشغيل كأيتام. يتيح لك &lt;code&gt;KillOnParentExit&lt;/code&gt; الإعلان عند بدء العملية بأن العملية الفرعية يجب إنهاؤها عند إنهاء العملية الوالدة.&lt;/p&gt;
&lt;p&gt;هذه ميزة كانت موجودة بطرق خاصة بالمنصة (كائنات المهام على Windows، وprctl على Linux) لكنها كانت تتطلب p/invoke أو مكتبات طرف ثالث للاستخدام من .NET. الآن أصبحت خاصية من الدرجة الأولى على &lt;code&gt;ProcessStartInfo&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="واجهات-api-المستندة-إلى-safeprocesshandle"&gt;واجهات API المستندة إلى SafeProcessHandle&lt;/h2&gt;
&lt;p&gt;سطح API الخفيف الجديد مبني حول &lt;code&gt;SafeProcessHandle&lt;/code&gt; بدلاً من الفئة &lt;code&gt;Process&lt;/code&gt; الكاملة. الفئة &lt;code&gt;Process&lt;/code&gt; الكاملة تحمل الكثير من الحالة وصعبة التقليص — مسار &lt;code&gt;SafeProcessHandle&lt;/code&gt; أكثر توافقًا مع المُقلِّص للتطبيقات التي تحتاج إلى تصغير حجم المخرجات (WASM، AOT الأصلي).&lt;/p&gt;
&lt;h2 id="تحكم-كامل-في-وراثة-المقابض"&gt;تحكم كامل في وراثة المقابض&lt;/h2&gt;
&lt;p&gt;يضيف التحديث أيضًا تحكمًا دقيقًا في المقابض التي يرثها العملية الفرعية وكيفية إعادة توجيه المقابض القياسية. في السابق كان بإمكانك إعادة توجيه stdin/stdout/stderr لكن لم يكن بإمكانك تحديد المقابض التي ترث بالضبط على مستوى نظام التشغيل. تعرض واجهات برمجة التطبيقات الجديدة هذا التحكم.&lt;/p&gt;
&lt;h2 id="لماذا-هذا-مهم"&gt;لماذا هذا مهم&lt;/h2&gt;
&lt;p&gt;تُستخدم فئة &lt;code&gt;Process&lt;/code&gt; في الأدوات، وأنظمة البناء، ومشغّلات الاختبارات، وأي تطبيق يستدعي ملفات قابلة للتنفيذ أخرى. كان سطح API القديم يعود إلى .NET Framework وكان يُظهر عمره. هذا ليس تغييرًا كاسرًا للتوافق — واجهات برمجة التطبيقات القديمة لا تزال تعمل — لكن الكود الجديد يجب أن يفضل السطح الجديد.&lt;/p&gt;
&lt;p&gt;للتطبيقات المُقلَّصة أو سيناريوهات الترجمة AOT، يُرحَّب بشكل خاص بمسار &lt;code&gt;SafeProcessHandle&lt;/code&gt;. كانت فئة &lt;code&gt;Process&lt;/code&gt; القديمة تجلب الكثير من الكود كثيف الانعكاسات الذي كان يعقّد التقليص.&lt;/p&gt;
&lt;p&gt;المنشور الأصلي: &lt;a href="https://devblogs.microsoft.com/dotnet/process-api-improvements-in-dotnet-11/"&gt;Process API Improvements in .NET 11&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>كيف انتقل Copilot Studio إلى .NET 10 WebAssembly وأصبح أسرع بنسبة 20%</title><link>https://thedotnetblog.com/ar/news/emiliano-montesdeoca/copilot-studio-net10-webassembly-migration-performance/</link><pubDate>Sat, 23 May 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ar/news/emiliano-montesdeoca/copilot-studio-net10-webassembly-migration-performance/</guid><description>تحسينات .NET 10 WASM ليست فقط للمشاريع الجديدة. إليك ما قاسه Copilot Studio بعد الترقية من .NET 8: بصمة تلقائية للملفات، WasmStripILAfterAOT افتراضياً وأرقام أداء تنفيذ حقيقية.</description><content:encoded>&lt;p&gt;قام فريق Copilot Studio بشيء كان فضوليًا بشأنه جميع مطوري Blazor WASM: لقد قاموا فعليًا بترقية تطبيق إنتاجي من .NET 8 إلى .NET 10 وقاسوا النتائج. يشارك المنشور أرقامًا محددة، وهو أمر نادر ومفيد حقًا.&lt;/p&gt;
&lt;h2 id="الترقية-كانت-مملة-هذا-أمر-جيد"&gt;الترقية كانت مملة (هذا أمر جيد)&lt;/h2&gt;
&lt;p&gt;تحديث إطار العمل المستهدف، تحديث مراجع الحزم، إصلاح التغييرات المخلة. هذا كل شيء. بناء .NET 10 يعمل الآن في الإنتاج. الهجرة نفسها لم تكن الجزء المثير للاهتمام — التغييرات في .NET 10 هي ذلك.&lt;/p&gt;
&lt;h2 id="البصمة-التلقائية-للأصول"&gt;البصمة التلقائية للأصول&lt;/h2&gt;
&lt;p&gt;في السابق، كان توزيع تطبيق WASM يعني كتابة نصوص برمجية مخصصة لإعادة تسمية الأصول المنشورة بتجزئات SHA256 لتجاوز التخزين المؤقت. كان لدى Copilot Studio نص PowerShell يقوم بهذا بالضبط — إعادة تسمية الملفات، حقن سمات &lt;code&gt;integrity&lt;/code&gt; في محمّل JavaScript، إدارة كل شيء يدويًا.&lt;/p&gt;
&lt;p&gt;في .NET 10، كل ذلك مدمج. يتم وضع بصمة تلقائية على الأصول المنشورة، واستيرادها مباشرة من &lt;code&gt;dotnet.js&lt;/code&gt;، والتحقق من سلامتها دون تدخل يدوي. قام الفريق بحذف نص إعادة التسمية.&lt;/p&gt;
&lt;p&gt;تغيير صغير في النطاق، تخفيض كبير في التعقيد.&lt;/p&gt;
&lt;h2 id="wasmstripilafteraot-مفعل-الآن-افتراضيا"&gt;WasmStripILAfterAOT مفعّل الآن افتراضيًا&lt;/h2&gt;
&lt;p&gt;في .NET 8، كان إزالة IL من التجميعات المترجمة بـ AOT اختياريًا. في .NET 10 هو السلوك الافتراضي. بعد ترجمة AOT، يتم إزالة رمز IL الأصلي من المخرجات — غير مطلوب في وقت التشغيل، والاحتفاظ به كان يضخم حجم الحزمة دون سبب.&lt;/p&gt;
&lt;p&gt;يستخدم Copilot Studio تحسينًا محددًا: يوزع كلًا من محرك JIT (بدء سريع) ومحرك AOT (أقصى أداء في الحالة الثابتة)، يحمّل كليهما بالتوازي وينتقل من JIT إلى AOT بمجرد استعداده. كما يُزيل تكرار الملفات المتطابقة بين المحركَين.&lt;/p&gt;
&lt;p&gt;يعني سلوك إزالة IL الجديد أن تجميعات AOT لم تعد تطابق نظيراتها من JIT بشكل بت ببت، لذا تُزال تكرارات ملفات أقل:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET 8: 59 ملفًا مشتركًا&lt;/li&gt;
&lt;li&gt;.NET 10: 22 ملفًا مشتركًا&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;النتيجة الصافية: حجم حزمة أكبر بحوالي 15% لمحرك AOT. تنزيل AOT أبطأ بحوالي 6% على شبكة LAN السريعة، وأبطأ بحوالي 17% على 4G. لكن كل ذلك يحدث في الخلفية بعد أن يصبح التطبيق تفاعليًا بالفعل.&lt;/p&gt;
&lt;h2 id="أرقام-الأداء"&gt;أرقام الأداء&lt;/h2&gt;
&lt;p&gt;هذا هو الجزء المهم:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;أسرع بحوالي 20%&lt;/strong&gt; في المكالمة الأولى (المسار البارد)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;أسرع بحوالي 5%&lt;/strong&gt; في المكالمات اللاحقة (المسار الدافئ)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;التحسينات أكثر وضوحًا في &amp;ldquo;البوتات الكبيرة&amp;rdquo; — العملاء الكبيرة والمعقدة حيث يهيمن الكود المترجم بـ AOT. لسير العمل الأبسط، الكسب أصغر.&lt;/p&gt;
&lt;h2 id="إذا-كنت-لا-تزال-على-net-8"&gt;إذا كنت لا تزال على .NET 8&lt;/h2&gt;
&lt;p&gt;قصة الهجرة بسيطة بحق: حدّث &lt;code&gt;&amp;lt;TargetFramework&amp;gt;&lt;/code&gt;، حدّث مراجع الحزم، احذف أي نصوص بصمة مخصصة، وستستفيد تلقائيًا من &lt;code&gt;WasmStripILAfterAOT&lt;/code&gt;. إذا كنت تترجم بـ AOT، توقع مكاسب مماثلة في الأداء.&lt;/p&gt;
&lt;p&gt;ملاحظة من المنشور: إذا كنت تحمّل وقت تشغيل .NET WASM داخل &lt;code&gt;WebWorker&lt;/code&gt;، اضبط &lt;code&gt;dotnetSidecar = true&lt;/code&gt; عند التهيئة.&lt;/p&gt;
&lt;p&gt;المنشور الأصلي: &lt;a href="https://devblogs.microsoft.com/dotnet/copilot-studio-dotnet-10-migration/"&gt;Copilot Studio gets faster with .NET 10 on WebAssembly&lt;/a&gt;&lt;/p&gt;</content:encoded></item></channel></rss>