paint-brush
Async ইভেন্টহ্যান্ডলারদের জন্য একটি সহজ নিরাপত্তা নেটদ্বারা@devleader
814 পড়া
814 পড়া

Async ইভেন্টহ্যান্ডলারদের জন্য একটি সহজ নিরাপত্তা নেট

দ্বারা Dev Leader8m2023/02/14
Read on Terminal Reader
Read this story w/o Javascript

অতিদীর্ঘ; পড়তে

Async void একমাত্র ব্যতিক্রম যা আমরা ভয়ঙ্কর async EventHandlers সেটআপের জন্য অনুমতি দিচ্ছি বলে মনে হয়। এই নিবন্ধে, আমি আরেকটি সমাধান উপস্থাপন করব যা আপনি নিজের কোডে চেষ্টা করতে পারেন। এটি কীভাবে ব্যবহার করা যেতে পারে সে সম্পর্কে আমরা আমার দৃষ্টিকোণ থেকে পক্ষ-বিপক্ষের বিষয়ে আলোচনা করব যাতে আপনি সিদ্ধান্ত নিতে পারেন যে এটি অর্থপূর্ণ কিনা।
featured image - Async ইভেন্টহ্যান্ডলারদের জন্য একটি সহজ নিরাপত্তা নেট
Dev Leader HackerNoon profile picture

যখন আমরা async EventHandlers নিয়ে আলোচনা করি, তখন আমাদের অনেকের মনে প্রথম যে বিষয়টি আসে তা হল এটি একমাত্র ব্যতিক্রম যা আমরা অনুমতি দিই বলে মনে হয় ভয়ঙ্কর অ্যাসিঙ্ক অকার্যকর সেটআপ .


যখন আমি এর আগে এই বিষয়ে লিখেছিলাম, তখন আমি উত্তেজিত ছিলাম যে আমি এমন একটি সমাধান অন্বেষণ করছিলাম যা আসলে অ্যাসিঙ্ক শূন্যতার অস্তিত্বের অনুমতি দেয় (আমার বাকি চুলগুলি টানতে না চাওয়া ছাড়া)।


আমার জন্য, এটি কিছু চতুর কৌশল সম্পর্কে ছিল যা আমরা সম্পূর্ণরূপে সমস্যা এড়ানোর জন্য সমাধান প্রদানের চেয়ে অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারগুলিকে কাটিয়ে উঠতে ব্যবহার করতে পারি।


যদিও এটি বলার সাথে সাথে, নিবন্ধটিতে প্রচুর ট্র্যাকশন ছিল, যার জন্য আমি খুব কৃতজ্ঞ, এবং কিছু লোক মতামত প্রকাশ করেছে যে তারা বরং অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারগুলিকে অন্য উপায়ে সমাধান করবে।


আমি ভেবেছিলাম এটি একটি দুর্দান্ত পয়েন্ট ছিল, তাই আমি একটি বিকল্প পদ্ধতি নিয়ে আসতে চেয়েছিলাম যা অ্যাসিঙ্ক শূন্যতাকে ঠিক করে না, তবে এটি আপনাকে কিছু চ্যালেঞ্জের সমাধান করার সময় এটিকে সম্পূর্ণরূপে বাতিল করতে দেয় (দেখুন আমি সেখানে কী করেছি?) async ইভেন্টহ্যান্ডলারের সাথে।


এই নিবন্ধে, আমি আরেকটি সমাধান উপস্থাপন করব যা আপনি নিজের কোডে চেষ্টা করতে পারেন। এটি কীভাবে ব্যবহার করা যেতে পারে সে সম্পর্কে আমরা আমার দৃষ্টিকোণ থেকে ভাল এবং অসুবিধাগুলিকে সম্বোধন করব যাতে আপনি সিদ্ধান্ত নিতে পারেন যে এটি আপনার ব্যবহারের ক্ষেত্রে অর্থপূর্ণ কিনা।


আপনি .NET বেহালার ডানদিকে কিছু ইন্টারঅ্যাক্টেবল কোডও খুঁজে পেতে পারেন এখানে . অন্যথায়, আপনি পারেন GitHub এ কোডটি পরীক্ষা করুন আপনি যদি এটি চেষ্টা করার জন্য স্থানীয়ভাবে এটি ক্লোন করতে চান।

একটি সঙ্গী ভিডিও!

এখানে ক্লিক করুন ভিডিও চেক আউট করতে!

সমস্যাটি

অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারের সাথে আমরা যে সমস্যার মুখোমুখি হচ্ছি তা হল যে ইভেন্টগুলির জন্য স্বাক্ষর যা আমরা ডিফল্টরূপে C# এ সাবস্ক্রাইব করতে পারি তা এইরকম দেখায়:


 void TheObject_TheEvent(object sender, EventArgs e);


এবং, আপনি লক্ষ্য করবেন যে এই স্বাক্ষরের সামনে অকার্যকর করে, আমরা ইভেন্টে সদস্যতা নেওয়ার জন্য আমাদের নিজস্ব হ্যান্ডলারে অকার্যকর ব্যবহার করতে বাধ্য হচ্ছি।


এর মানে হল যে আপনি যদি চান যে আপনার হ্যান্ডলার কখনও অ্যাসিঙ্ক/ওয়েট কোড চালাতে, তাহলে আপনাকে আপনার অকার্যকর পদ্ধতির মধ্যে অপেক্ষা করতে হবে... যা বড় ভীতিকর অ্যাসিঙ্ক অকার্যকর প্যাটার্ন উপস্থাপন করে যা আমাদের প্লেগের মতো এড়াতে বলা হয়েছে।


এবং কেন? কারণ async void ব্যতিক্রমগুলির জন্য সঠিকভাবে বুদবুদ হওয়ার ক্ষমতা ভঙ্গ করে এবং এর ফলে এক টন মাথাব্যথা হতে পারে।


আগের প্রবন্ধ আমাদের জিনিসের আহ্বানের দিকে সৃজনশীল হওয়ার অনুমতি দিয়ে এটিকে সম্বোধন করেছে কিন্তু…


  • আমরা যে বস্তুগুলির জন্য ইভেন্টের আহ্বান নিয়ন্ত্রণ করি না (অর্থাৎ, আপনি আপনার প্রিয় UI ফ্রেমওয়ার্কের একটি বোতামের ক্লিক ইভেন্টে হুক আপ করছেন) সেগুলির জন্য আমাদের সমর্থনের প্রয়োজন হতে পারে


  • কিছু লোক সেই সমাধানের ভিতরে প্রসঙ্গটির ব্যবহারকে হ্যাক হিসাবে দেখেন (আমি এর সাথে একমত নই)।


  • … বিশেষত, ইভেন্ট হ্যান্ডলারদের সাথে, আমাদের কাছে আরও কিছু সহজ কৌশল রয়েছে যা আমরা অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারদের সমর্থন করতে করতে পারি!


আমার মতে, সহজ হল আরও ভাল... সুতরাং আপনি যদি অ্যাসিঙ্ক ভ্যায়েডের উপর আমার আগের নিবন্ধটি পড়েন এবং আপনার লক্ষ্য সত্যিই ইভেন্টহ্যান্ডলারদের সাথে মোকাবিলা করা ছিল, তাহলে এটি সাহায্য করবে।

ট্রাই/ক্যাচ দিয়ে Async ইভেন্টহ্যান্ডলার সমাধান করা

পূর্বে উল্লিখিত শর্তের উপর ভিত্তি করে, ব্যতিক্রম হ্যান্ডলিং অ্যাসিঙ্ক শূন্যতার সীমানা ভেঙ্গে যায়। আপনি যদি এই সীমানা অতিক্রম করার জন্য বুদ্বুদ আপ করতে হবে এমন একটি ব্যতিক্রম থাকে, তাহলে আপনি একটি মজার সময় কাটাতে যাচ্ছেন।


এবং মজার দ্বারা, আমি বলতে চাচ্ছি যে আপনি যদি ডিবাগিং উপভোগ করেন কেন স্টাফ কাজ করছে না এবং আপনার কাছে স্পষ্ট ইঙ্গিত নেই যে কী ভাঙছে, তাহলে আপনি সত্যিই একটি দুর্দান্ত সময় কাটাবেন।


তাই এটি ঠিক করার সবচেয়ে সহজ উপায় কি?


আসুন একটি সাধারণ টুল ব্যবহার করে প্রথমে এই সীমানা অতিক্রম করতে সক্ষম হওয়া থেকে ব্যতিক্রমগুলি প্রতিরোধ করি: চেষ্টা করুন/ক্যাচ করুন৷


 objectThatRaisesEvent.TheEvent += async (s, e) => { // if the try catch surrounds EVERYTHING in the handler, no exception can bubble up try { await SomeTaskYouWantToAwait(); } catch (Exception ex) { // TODO: put your exception handling stuff here } // no exception can escape here if the try/catch surrounds the entire handler body }


উপরের কোডে উল্লিখিত হিসাবে, আপনি যদি আপনার ইভেন্ট হ্যান্ডলারের পুরো অংশের চারপাশে একটি চেষ্টা/ক্যাচ ব্লক রাখেন, তাহলে আপনি সেই অ্যাসিঙ্ক অকার্যকর সীমানা জুড়ে বুদবুদ হওয়া থেকে কোনো ব্যতিক্রম প্রতিরোধ করতে পারেন। পৃষ্ঠে, এটি বেশ সহজ এবং এটি বাস্তবায়নের জন্য অভিনব কিছুর প্রয়োজন নেই।


সুবিধা:

  • অত্যন্ত সহজ. বোঝার জন্য কোন জটিল প্রক্রিয়া নেই।


  • কোন প্যাকেজ প্রয়োজন.


  • এটি কাজ করার জন্য ইভেন্টটি উত্থাপন করে এমন ক্লাসের মালিক হওয়ার প্রয়োজন নেই৷ এর মানে হল এই পদ্ধতিটি WinForms এবং WPF UI উপাদান সহ বিদ্যমান সমস্ত ইভেন্ট-উত্থাপন বস্তুর জন্য কাজ করবে।


অসুবিধা:

  • আপনাকে এটি করতে মনে রাখতে হবে... সর্বত্র।


  • এটা সম্ভব যে আপনার কোড সময়ের সাথে সাথে বিকশিত হওয়ার সাথে সাথে, কেউ ঘটনাক্রমে ইভেন্ট হ্যান্ডলারের চেষ্টা-ক্যাচের বাইরে যুক্তি লিখতে পারে যা ব্যতিক্রমগুলি ফেলতে পারে


যে বলে, এই সমাধান সত্যিই সহজ, কিন্তু আমি মনে করি আমরা একটু ভাল করতে পারি।

অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারের উন্নতির জন্য একটি (সামান্য) অভিনব পদ্ধতি

একটি উন্নতি যা আমি মনে করি আমরা প্রাথমিকভাবে প্রস্তাবিত সমাধানটি তৈরি করতে পারি তা হল আমরা এটিকে আরও কিছুটা স্পষ্ট করতে পারি যে আমাদের কাছে একটি অ্যাসিঙ্ক ইভেন্টহ্যান্ডলার রয়েছে যা ব্যতিক্রমগুলিকে বুদবুদ করা থেকে নিরাপদ হওয়া উচিত।


এই পদ্ধতিটি ইভেন্ট হ্যান্ডলারের বাইরে চলা থেকে সমস্যাযুক্ত কোডকে সময়ের সাথে সাথে কোড ড্রিফ্টকে প্রতিরোধ করবে। যাইহোক, এটি আপনাকে ম্যানুয়ালি এটি যোগ করার জন্য মনে রাখতে হবে এমন বিষয়টির সমাধান করবে না!


আসুন কোডটি পরীক্ষা করে দেখি:

 static class EventHandlers { public static EventHandler<TArgs> TryAsync<TArgs>( Func<object, TArgs, Task> callback, Action<Exception> errorHandler) where TArgs : EventArgs => TryAsync<TArgs>( callback, ex => { errorHandler.Invoke(ex); return Task.CompletedTask; }); public static EventHandler<TArgs> TryAsync<TArgs>( Func<object, TArgs, Task> callback, Func<Exception, Task> errorHandler) where TArgs : EventArgs { return new EventHandler<TArgs>(async (object s, TArgs e) => { try { await callback.Invoke(s, e); } catch (Exception ex) { await errorHandler.Invoke(ex); } }); } }


উপরের কোডটি বেশ আক্ষরিক অর্থেই অ্যাসিঙ্ক অকার্যকর সীমানা অতিক্রম করা থেকে ব্যতিক্রম প্রতিরোধের জন্য একই পদ্ধতি ব্যবহার করে। আমরা কেবল ইভেন্ট হ্যান্ডলারের শরীরের চারপাশে ধরার চেষ্টা করি, কিন্তু এখন আমরা এটিকে পুনঃব্যবহারের জন্য একটি সুস্পষ্টভাবে উত্সর্গীকৃত পদ্ধতিতে বান্ডিল করেছি।


এটি প্রয়োগ করতে এটি দেখতে কেমন হবে তা এখানে:


 someEventRaisingObject.TheEvent += EventHandlers.TryAsync<EventArgs>( async (s, e) => { Console.WriteLine("Starting the event handler..."); await SomeTaskToAwait(); Console.WriteLine("Event handler completed."); }, ex => Console.WriteLine($"[TryAsync Error Callback] Our exception handler caught: {ex}"));


আমরা দেখতে পাচ্ছি যে আমাদের কাছে এখন কাজ করার জন্য একটি async টাস্ক স্বাক্ষর সহ একজন প্রতিনিধি আছে, এবং আমরা যা কিছু রেখেছি তা আমরা নিশ্চিত করেছি যে সাহায্যকারী পদ্ধতিতে আমরা আগে দেখেছি তার চারপাশে চেষ্টা/ক্যাচ করা হবে।


এখানে ত্রুটি হ্যান্ডলার কলব্যাক সঠিকভাবে ব্যতিক্রম ক্যাপচার দেখানো একটি স্ক্রিনশট:


অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারের জন্য উদাহরণ প্রোগ্রামের আউটপুট

সুবিধা:


  • এখনও খুব সহজ. র‍্যাপার ফাংশনটি *সামান্য* আরও জটিল, তবে এখনও খুব মৌলিক।


  • কোন প্যাকেজ প্রয়োজন.


  • এটি কাজ করার জন্য ইভেন্টটি উত্থাপন করে এমন ক্লাসের মালিক হওয়ার প্রয়োজন নেই৷ এর মানে হল এই পদ্ধতিটি WinForms এবং WPF UI উপাদান সহ বিদ্যমান সমস্ত ইভেন্ট-উত্থাপন বস্তুর জন্য কাজ করবে।


  • ইভেন্টে হ্যান্ডলারকে হুক করার সময় সিনট্যাক্সের কারণে অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারের সাথে কাজ করার উদ্দেশ্যটি আরও স্পষ্ট।


  • কোড ড্রিফ্ট যা শেষ পর্যন্ত আরও ব্যতিক্রম ছুঁড়ে দেয় তা এখনও চেষ্টা/ক্যাচের ভিতরে মোড়ানো হবে


অসুবিধা:


  • আপনি এখনও এই জিনিস হুক আপ মনে রাখা প্রয়োজন!

Async EventHandlers সম্পর্কে চিন্তাভাবনা বন্ধ করা

মূলত আমি অন্বেষণ করতে সেট আউট অ্যাসিঙ্ক শূন্যতা মোকাবেলা করার আকর্ষণীয় উপায় , পাঠকের প্রতিক্রিয়া বৈধ ছিল যে উদাহরণগুলি async EventHandlers এর উপর দৃষ্টি নিবদ্ধ করে এবং অবশ্যই একটি আরও সহজ উপায় থাকতে হবে।


এই নিবন্ধে, আমরা অন্বেষণ করেছি যে আমি যুক্তি দিতে পারি তা হল আপনার অ্যাসিঙ্ক ইভেন্টহ্যান্ডলারদের সঠিকভাবে আচরণ করার সবচেয়ে সহজ উপায়, এবং পরিমার্জিত সমাধানে (আমার মতে) শুধুমাত্র সেই ত্রুটি রয়েছে যা আপনাকে এটি ব্যবহার করার জন্য মনে রাখতে হবে।


একজন মন্তব্যকারী পরামর্শ দিয়েছিলেন যে কেউ অন্বেষণ করতে পারে দৃষ্টিভঙ্গি ওরিয়েন্টেড প্রোগ্রামিং (AoP) আপনার অ্যাপ্লিকেশন জুড়ে এই ধরণের আচরণ ইনজেক্ট করার জন্য যাতে আপনাকে এটি করার জন্য মনে রাখতে না হয়।


কিছু কম্পাইল-টাইম AoP ফ্রেমওয়ার্ক রয়েছে যা বিদ্যমান, তবে আমি পাঠক হিসাবে এটি আপনার জন্য একটি অনুশীলন হিসাবে রেখে দেব (কারণ এটি আমার পক্ষে অনুসরণ করাও একটি অনুশীলন)।