এখনও অবধি আমি থ্রেডিং টাইমারের পরিবর্তে চক্রীয় সিপিইউ বাউন্ড ব্যাকগ্রাউন্ড কাজের জন্য একটি লংআরনিং টিপিএল টাস্ক ব্যবহার করেছি, কারণ:
- টিপিএল টাস্ক বাতিলকে সমর্থন করে
- প্রোগ্রামিং বন্ধ হয়ে যাওয়ার সময় থ্রেডিং টাইমার আরেকটি থ্রেড শুরু করতে পারে যখন নিষ্পত্তিযোগ্য সংস্থানগুলির সাথে সম্ভাব্য সমস্যা তৈরি করে
- ওভাররুনের সুযোগ: থ্রেডিং টাইমারটি অন্য থ্রেড শুরু করতে পারে যখন অপ্রত্যাশিত দীর্ঘ কাজের কারণে পূর্ববর্তীটি এখনও প্রক্রিয়া করা হয় (আমি জানি, এটি টাইমারটি থামিয়ে এবং পুনরায় চালু করে প্রতিরোধ করা যেতে পারে)
যাইহোক, টিপিএল সমাধান সর্বদা একটি উত্সর্গীকৃত থ্রেডের দাবি করে যা পরবর্তী ক্রিয়াটির (যা বেশিরভাগ সময়) অপেক্ষা করার সময় প্রয়োজন হয় না। আমি জেফের প্রস্তাবিত সমাধানটি ব্যাকগ্রাউন্ডে সিপিইউ বাউন্ড সাইক্লিক কাজ সম্পাদন করতে ব্যবহার করতে চাই কারণ যখন কেবল এমন কাজ করার সময় থ্রেডপুলের থ্রেডের প্রয়োজন হয় যা স্কেলিবিলিটির জন্য ভাল (বিশেষত যখন অন্তরকাল বড় হয়)।
এটি অর্জনের জন্য, আমি 4 টি অভিযোজন প্রস্তাব করব:
- যোগ
ConfigureAwait(false)
করার জন্য Task.Delay()
চালানো doWork
, একটি থ্রেড পুল থ্রেডে কর্ম অন্যথায় doWork
যা উপমা ধারণা নয় কলিং থ্রেডে সঞ্চালন করা হবে
- একটি কার্যক্যান্সেলড এক্সসেপশন (এখনও প্রয়োজনীয়?) ছুঁড়ে দিয়ে বাতিল প্যাটার্নটিতে লেগে থাকুন
doWork
কাজটি বাতিল করতে সক্ষম করার জন্য বাতিলকরণ টোকেনকে ফরোয়ার্ড করুন
- টাস্কের স্টেটের তথ্য সরবরাহ করার জন্য টাইপ অবজেক্টের একটি প্যারামিটার যুক্ত করুন (একটি টিপিএল টাস্কের মতো)
পয়েন্ট 2 সম্পর্কে আমি নিশ্চিত নই, async অপেক্ষা করার জন্য এখনও টাস্ক ক্যান্সেলড এক্সেকশন প্রয়োজন বা এটি কেবল সেরা অনুশীলন?
public static async Task Run(Action<object, CancellationToken> doWork, object taskState, TimeSpan period, CancellationToken cancellationToken)
{
do
{
await Task.Delay(period, cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
doWork(taskState, cancellationToken);
}
while (true);
}
প্রস্তাবিত সমাধানটিতে আপনার মন্তব্য দিন ...
আপডেট 2016-8-30
উপরের সমাধানটি তাত্ক্ষণিকভাবে কল করে না doWork()
তবে await Task.Delay().ConfigureAwait(false)
থ্রেড সুইচটির জন্য শুরু করে doWork()
। নীচের সমাধানটি প্রথম doWork()
কলটি একটিতে মোড়ক করে তার জন্য Task.Run()
অপেক্ষা করে এই সমস্যাটি কাটিয়ে উঠেছে ।
নীচে উন্নত অ্যাসিঙ্ক replacement প্রতিস্থাপনের জন্য অপেক্ষা করা হয়েছে Threading.Timer
যার জন্য বাতিলযোগ্য চক্রীয় কাজ সম্পাদন করে এবং স্কেলযোগ্য (টিপিএল সমাধানের সাথে তুলনা করে) কারণ পরবর্তী পদক্ষেপের জন্য অপেক্ষা করার সময় এটি কোনও থ্রেড দখল করে না।
নোট করুন যে টাইমার বিপরীতে, অপেক্ষার সময় ( period
) স্থির এবং চক্র সময় নয়; চক্রের সময়টি অপেক্ষার সময়ের যোগফল এবং তার সময়কাল doWork()
পরিবর্তিত হতে পারে।
public static async Task Run(Action<object, CancellationToken> doWork, object taskState, TimeSpan period, CancellationToken cancellationToken)
{
await Task.Run(() => doWork(taskState, cancellationToken), cancellationToken).ConfigureAwait(false);
do
{
await Task.Delay(period, cancellationToken).ConfigureAwait(false);
cancellationToken.ThrowIfCancellationRequested();
doWork(taskState, cancellationToken);
}
while (true);
}