البرمجة التفاعلية في C# (.NET): Observable و Rx.NET والعمل مع تدفقات البيانات
البرمجة التفاعلية (Reactive Programming) هي نموذج يركز على المعالجة غير المتزامنة لتدفقات البيانات ونشر التغييرات. في بيئة C# (.NET)، يتم تنفيذ هذا المفهوم من خلال مكتبة Rx.NET (Reactive Extensions) والواجهات IObservable<T> / IObserver<T>. على عكس النهج الأمري التقليدي، تسمح البرمجة التفاعلية بوصف كيفية استجابة النظام للأحداث بشكل تصريحي، دون حظر سير التنفيذ الرئيسي.
في صفحة PythonLib، سنستعرض المكونات الرئيسية للبرمجة التفاعلية في C#، بما في ذلك تسلسلات Observable، وعوامل LINQ لتحويل التدفقات، وأمثلة عملية للاستخدام.
المفاهيم الأساسية للبرمجة التفاعلية في C#
تعتمد البرمجة التفاعلية على نمط Observer، حيث:
- Observable — مصدر البيانات (تدفق الأحداث).
- Observer — المشترك الذي يستجيب للبيانات الواردة.
- Subscription — آلية إدارة الاشتراك (إلغاء الاشتراك من التدفق).
في .NET، يتم تمثيل هذه المفاهيم بواسطة الواجهات IObservable<T> و IObserver<T>، ولكن عمليًا يتم استخدام مكتبة Rx.NET (حزمة NuGet System.Reactive) التي توفر مجموعة غنية من العوامل للعمل مع التسلسلات.
تثبيت Rx.NET
للبدء، أضف حزمة NuGet إلى مشروعك:
Install-Package System.Reactiveأو عبر .NET CLI:
dotnet add package System.Reactiveإنشاء Observable والاشتراك في تدفق البيانات
لننظر إلى مثال بسيط: سننشئ Observable يولد أرقامًا من 1 إلى 5 مع تأخير، ونشترك فيه.
using System;using System.Reactive.Linq;using System.Threading.Tasks;
class Program{ static async Task Main() { // إنشاء تسلسل Observable var observable = Observable.Interval(TimeSpan.FromSeconds(1)) .Select(x => x + 1) // البدء من 1 .Take(5); // أخذ 5 عناصر فقط
// الاشتراك في التدفق var subscription = observable.Subscribe( onNext: value => Console.WriteLine($"تم الاستلام: {value}"), onError: error => Console.WriteLine($"خطأ: {error.Message}"), onCompleted: () => Console.WriteLine("تم إنهاء التدفق") );
// انتظار الانتهاء (في الكود الحقيقي استخدم await أو حظر) await Task.Delay(6000);
// إلغاء الاشتراك (تحرير الموارد) subscription.Dispose(); }}عوامل LINQ لتحويل التدفقات
إحدى المزايا الرئيسية لـ Rx.NET هي إمكانية تطبيق عوامل مألوفة من LINQ على تدفقات البيانات: Where، Select، Aggregate وغيرها. وهذا يسمح بوصف التحويلات بشكل تصريحي.
مثال: التصفية والتحويل
using System;using System.Reactive.Linq;
var numbers = Observable.Range(1, 10);
var processed = numbers .Where(n => n % 2 == 0) // الأرقام الزوجية فقط .Select(n => n * n) // التربيع .Do(n => Console.WriteLine($"تمت المعالجة: {n}")); // تأثير جانبي
processed.Subscribe( onNext: n => Console.WriteLine($"النتيجة: {n}"), onCompleted: () => Console.WriteLine("تم"));دمج تدفقات متعددة
يدعم Rx.NET دمج وضم وتركيب التدفقات. على سبيل المثال، Merge يدمج عدة Observable في واحد:
<