اقرأ في هذا المقال
- إلغاء عمليات الإدخال والإخراج المعلقة
- أهمية إلغاء عمليات الإدخال والإخراج
- إلغاء الإدخال / الإخراج غير المتزامن
- إلغاء الإدخال / الإخراج المتزامن
يعمل المستخدم على إلغاء طلبات أجهزة الإدخال والإخراج المعلقة أو الغير مستجيبة والبطيئة حتى يتم تحسين القدرة على استخدام التطبيقات المختلفة على جهاز الكمبيوتر، وعملية الإلغاء هذه تعتبر أفضل من عملية إعادة الاستدعاء مرة أخرى والذي يؤدي إلى بطء عمل نظام التشغيل بشكل عام وعدم القدرة على استخدام أجهزة الإدخال والإخراج بشكل سليم.
إلغاء عمليات الإدخال والإخراج المعلقة
يمكن أن يؤدي السماح للمستخدمين بإلغاء طلبات الإدخال / الإخراج البطيئة أو المحظورة إلى تحسين قابلية استخدام التطبيق وقوته، على سبيل المثال، إذا تمّ حظر استدعاء لوظيفة (OpenFile) لأنّ عملية الاتصال بجهاز بطيء للغاية، فإنّ إلغاؤه يمكّن أن تكون طريقة أفضل من إجراء استدعاء له مرة أخرى، مع معلمات جديدة، دون إنهاء التطبيق، يوسع نظام التشغيل (Windows Vista) إمكانيات الإلغاء ويتضمن دعمًا لإلغاء العمليات المتزامنة.
ملاحظة: استدعاء دالة (CancelIoEx) لا يضمن أنّه سيتم إلغاء عملية الإدخال / الإخراج؛ يجب أن يدعم الجهاز الطرفي الذي يتولى العملية الإلغاء ويجب أن تكون العملية في حالة يمكن إلغاؤها.
أهمية إلغاء عمليات الإدخال والإخراج
عند برمجة استدعاءات الإلغاء، ضع في اعتبارك الاعتبارات التالية:
- ليس هناك ما يضمن أنّ برامج التشغيل الأساسية تدعم الإلغاء بشكل صحيح.
- عند إلغاء الإدخال / الإخراج غير المتزامن، وعند عدم توفير بنية متراكبة للدالة (CancelIoEx)، تحاول الوظيفة إلغاء كافة عمليات الإدخال / الإخراج المعلقة على الملف في كافة مؤشرات الترابط (threads) في العملية، تتم معالجة كل مؤشر ترابط على حدة، لذلك بعد معالجة ال (thread)، قد يبدأ إدخال / إخراج آخر على الملف قبل أن يتم إلغاء إدخال / إخراج كافة مؤشرات الترابط الأخرى للملف، ممّا يتسبب في حدوث مشكلات في المزامنة.
- عند إلغاء الإدخال / الإخراج غير المتزامن، لا تقم بإعادة استخدام الهياكل المتداخلة مع الإلغاء المستهدف، بمجرد اكتمال عملية الإدخال / الإخراج “إمّا بنجاح أو مع حالة الإلغاء”، فلن يكون الهيكل المتداخل قيد الاستخدام من قبل النظام ويمكن إعادة استخدامه.
- عند إلغاء الإدخال / الإخراج المتزامن، يحاول استدعاء دالة (CancelSynchronousIo) إلغاء أي مكالمة متزامنة حالية على مؤشر الترابط، يجب أن تحرص على التأكد من صحة مزامنة الاستدعاءات؛ قد يتم إلغاء الاستدعاء الخاطئ في سلسلة من الاستدعاءات، على سبيل المثال، إذا تمّ استدعاء وظيفة (CancelSynchronousIo) لعملية متزامنة، (X)، تبدأ العملية (Y) فقط بعد اكتمال هذه العملية (X) “بشكل طبيعي أو مع وجود خطأ”، إذا بدأ مؤشر الترابط الذي يسمّى العملية (X) ثمّ استدعاء متزامن آخر لـ (X)، فقد يقاطع استدعاء الإلغاء طلب الإدخال / الإخراج الجديد هذا.
- عند إلغاء الإدخال / الإخراج المتزامن، يجب أن تدرك أن حالة السباق يمكن أن توجد كلما تمت مشاركة مؤشر ترابط (thread) بين أجزاء مختلفة من التطبيق، على سبيل المثال، باستخدام مؤشر ترابط تجمع مؤشرات الترابط.
ما هي العمليات التي لا يمكن إلغاؤها
لا يمكن إلغاء بعض الوظائف باستخدام وظيفة (CancelIo) أو (CancelIoEx) أو (CancelSynchronousIo)، تمّ تمديد بعض هذه الوظائف للسماح بالإلغاء، على سبيل المثال، وظيفة (CopyFileEx)، ويجب عليك استخدامها بدلاً من ذلك، بالإضافة إلى دعم الإلغاء، تحتوي هذه الوظائف أيضًا على عمليات رد اتصال مدمجة لدعمك عند تتبع تقدم العملية، الوظائف التالية لا تدعم الإلغاء:
- (CopyFile) يستخدم (CopyFileEx).
- (MoveFile) تستخدم (MoveFileWithProgress).
- (MoveFileEx) تستخدم (MoveFileWithProgress).
- (ReplaceFile).
إلغاء الإدخال / الإخراج غير المتزامن
يمكنك إلغاء الإدخال / الإخراج غير المتزامن من أي مؤشر ترابط (thread) في العملية التي أصدرت عملية الإدخال / الإخراج، يجب عليك تحديد المكان الذي تمّ إجراء الإدخال / الإخراج عليه، واختيارياً، الهيكل المتداخل الذي تمّ استخدامه لأداء الإدخال / الإخراج، يمكنك تحديد ما إذا كان الإلغاء قد حدث عن طريق فحص الحالة التي تمّ إرجاعها في البنية المتداخلة أو في رد الاتصال الكامل، تشير حالة (ERROR_OPERATION_ABORTED) إلى أنّه تمّ إلغاء العملية.
إلغاء الإدخال / الإخراج المتزامن
يمكنك إلغاء الإدخال / الإخراج المتزامن من أي مؤشر ترابط في العملية التي أصدرت عملية الإدخال / الإخراج، يجب تحديد المؤشر لمؤشر الترابط الذي يقوم حاليًا بتنفيذ عملية الإدخال / الإخراج، يوضح المثال التالي إجراءين روتينييين:
- تعد وظيفة (SynchronousIoWorker) عبارة عن مؤشر ترابط عامل يقوم بتنفيذ بعض عمليات الإدخال / الإخراج للملفات المتزامنة، بدءًا من استدعاء الوظيفة (CreateFile)، إذا كان الروتين ناجحًا، يمكن أن يتبع الروتين عمليات إضافية لم يتم تضمينها هنا، يمكن استخدام المتغير العام (gCompletionStatus) لتحديد ما إذا كانت جميع العمليات قد نجحت أو ما إذا كانت العملية قد فشلت أو تمّ إلغاؤها، يشير المتغير العام (dwOperationInProgress) إلى ما إذا كان إدخال / إخراج الملف لا يزال قيد التقدم.
الفحوصات اليدوية الإضافية، التي لم يتم تضمينها هنا، مطلوبة في وظيفة (SynchronousIoWorker) لضمان أنّه إذا تمّ طلب الإلغاء خلال الفترات القصيرة بين استدعاءات إدخال / إخراج الملف، فسيتم إلغاء بقية العمليات.
- تحاكي الدالة (MainUIThreadMessageHandler) معالج الاستدعاء ضمن إجراء إطار مؤشر ترابط واجهة المستخدم، يطلب المستخدم مجموعة من عمليات الملفات المتزامنة عن طريق النقر فوق عنصر تحكم، ممّا يؤدي إلى إنشاء استدعاء نافذ محدد بواسطة المستخدم “في القسم المحدد بواسطة (WM_MYSYNCOPS)”، يؤدي هذا إلى إنشاء مؤشر ترابط جديد باستخدام الدالة (CreateFileThread)، والتي تبدأ بعد ذلك وظيفة (SynchronousIoWorker).
يستمر مؤشر ترابط واجهة المستخدم لمعالجة الاستدعاءات أثناء تنفيذ مؤشر ترابط العامل الإدخال / الإخراج المطلوب، إذا قرر المستخدم إلغاء العمليات غير المكتملة “عادةً عن طريق النقر فوق زر إلغاء”، فإنّ الروتين “في القسم الذي تمّ وضع علامة عليه بواسطة (WM_MYCANCEL) يستدعي الدالة (CancelSynchronousIo) باستخدام مؤشر الترابط الذي تمّ إرجاعه بواسطة دالة (CreateFileThread).
ترجع الدالة (CancelSynchronousIo) مباشرةً بعد محاولة الإلغاء، أخيرًا، قد يطلب المستخدم أو التطبيق لاحقًا بعض العمليات الأخرى التي تعتمد على ما إذا كانت عمليات الملف قد اكتملت، في هذه الحالة، يتحقق الروتين “في القسم المحدد بواسطة (WM_PROCESSDATA)” أولاً من اكتمال العمليات ثمّ تنفيذ عمليات (clean-up operations).