টাস্কের মতো একই কাজ সম্পন্ন হওয়ার অপেক্ষায় রয়েছেন? ফলাফল?


117

আমি বর্তমানে স্টিফেন ক্লিয়ারির " সি # কুকবুক ইন কনকুরেন্সি " পড়ছি এবং আমি নিম্নলিখিত কৌশলটি লক্ষ্য করেছি:

var completedTask = await Task.WhenAny(downloadTask, timeoutTask);  
if (completedTask == timeoutTask)  
  return null;  
return await downloadTask;  

downloadTaskএটিতে একটি কল httpclient.GetStringAsync, এবং timeoutTaskকার্যকর করা হচ্ছে Task.Delay

ঘটনাটি শেষ না হয়ে গেলে downloadTaskইতিমধ্যে সম্পূর্ণ হয়ে গেছে। downloadTask.Resultকাজটি ইতিমধ্যে সম্পন্ন হয়ে গেছে কেন, ফেরার পরিবর্তে দ্বিতীয় প্রতীক্ষার প্রয়োজন কেন ?


3
এখানে কিছুটা প্রসঙ্গ নিখোঁজ রয়েছে এবং লোকেদের সহজেই বইটিতে অ্যাক্সেস না থাকলে আপনার এটিকে অন্তর্ভুক্ত করা দরকার। কি downloadTaskএবং timeoutTask? তারা কি করে?
মাইক পেরেনউড

7
আমি এখানে সফল সমাপ্তির জন্য আসল চেক দেখছি না। কাজের খুব ভাল faulted হতে পারে, এবং যে ক্ষেত্রে আচরণ করবে (আলাদা হতে AggregateExceptionসঙ্গে Resultমাধ্যমে বনাম প্রথম ব্যতিক্রম ExceptionDispatchInfoসঙ্গে await)। স্টিফেন টুবের "টাস্ক এক্সেপশন হ্যান্ডলিং ইন। নেট 4.5": ব্লগস.এমএসএনএন / বি / পিএফএক্সটিয়াম / আর্কাইভ / ২০১৮ / ২৯ / ২৮ )
কিরিল শ্লেনস্কি

আপনার এটি উত্তর দেওয়া উচিত @ কিরিলশ্লেনস্কি
কার্স্টেন

@ মিশেল পেরেনউড ঠিক বলেছেন, লক্ষ্য করার জন্য ধন্যবাদ, আমি প্রশ্নটি সম্পাদনা করব।
julio.g

উত্তর:


160

এখানে ইতিমধ্যে কিছু ভাল উত্তর / মন্তব্য রয়েছে তবে কেবল চিম ইন করতে ...

আমি awaitবেশি Result(বা Wait) বেশি পছন্দ করার দুটি কারণ রয়েছে । প্রথমটি হ'ল ত্রুটি পরিচালনার বিষয়টি আলাদা; awaitএকটি ব্যতিক্রম মোড়ানো না AggregateException। আদর্শভাবে, অ্যাসিক্রোনাস কোডটি কখনই একেবারেই মোকাবেলা করা উচিত AggregateExceptionনয়, যদি না এটি সুনির্দিষ্টভাবে না চায়

দ্বিতীয় কারণটি আরও কিছুটা সূক্ষ্ম। আমি আমার ব্লগে বর্ণনা হিসাবে (এবং গ্রন্থে), Result/ Waitডেডলক সৃষ্টি করতে পারে , এবং যখন একটি ব্যবহৃত আরও বেশি সূক্ষ্ম ডেডলক সৃষ্টি করতে পারে asyncপদ্ধতি । সুতরাং, যখন আমি কোডের মাধ্যমে পড়ছি এবং আমি একটি Resultবা দেখি Wait, এটি একটি তাত্ক্ষণিক সতর্কতা পতাকা। Result/ Waitশুধুমাত্র সঠিক হয় তাহলে তুমি পুরোপুরি নিশ্চিত যে কাজটি ইতিমধ্যে সম্পন্ন হয়। এটি কেবল এক নজরে (রিয়েল-ওয়ার্ল্ড কোডে) দেখতে পারা কঠিন নয়, কোড পরিবর্তনের ক্ষেত্রে এটি আরও ভঙ্গুর।

যে বলার নয় Result/ Waitউচিত না ব্যবহৃত হবে না। আমি আমার নিজস্ব কোডে এই নির্দেশিকাগুলি অনুসরণ করি:

  1. কোনও অ্যাপ্লিকেশনটিতে অ্যাসিঙ্ক্রোনাস কোডটি কেবল ব্যবহার করতে পারে await
  2. অ্যাসিঙ্ক্রোনাস ইউটিলিটি কোড (একটি লাইব্রেরিতে) মাঝে মাঝে ব্যবহার করতে পারে Result/ Waitযদি কোডটি সত্যই এটির জন্য কল করে। এই জাতীয় ব্যবহারের সম্ভবত মন্তব্য থাকতে হবে।
  3. সমান্তরাল টাস্ক কোড ব্যবহার করতে পারে Resultএবং Wait

দ্রষ্টব্য যে (1) এখন পর্যন্ত সাধারণ ক্ষেত্রে, তাই আমার awaitসর্বত্র ব্যবহার করার এবং অন্যান্য ক্ষেত্রে সাধারণ নিয়মের ব্যতিক্রম হিসাবে বিবেচনা করার প্রবণতা ।


আমরা আমাদের প্রকল্পগুলিতে 'অপেক্ষা' না করে 'ফলাফল' ব্যবহার করে অচলাবস্থার মুখোমুখি হয়েছি। এই গণ্ডগোলিত অংশটির কোনও সংকলন ত্রুটি নেই এবং কিছুক্ষণ পরে আপনার কোডটি ফ্ল্যাশ হয়ে যায়।
আহমদ মৌসভী

@ স্টিফেন আপনি দয়া করে আমাকে ব্যাখ্যা করবেন কেন "আদর্শভাবে, অ্যাসিঙ্ক্রোনাস কোডটি কখনই অ্যাগ্রিগ্রেট
এক্সেকশন

4
@vcRobe কারণ মোড়ককে awaitবাধা দেয় AggregateExceptionAggregateExceptionঅবিচ্ছিন্ন প্রোগ্রামিং নয়, সমান্তরাল প্রোগ্রামিংয়ের জন্য ডিজাইন করা হয়েছিল not
স্টিফেন ক্লিয়ারি

2
> "অপেক্ষাটি কেবলমাত্র সঠিক যদি আপনি নিশ্চিত হন যে টাস্কটি ইতিমধ্যে সম্পন্ন হয়েছে" " .... তাহলে কেন অপেক্ষা করা হয়?
রায়ান দ্য লিচ

4
@ রায়ান দ্য ল্যাচ: এর আসল উদ্দেশ্য Waitছিল ডায়নামিক টাস্ক প্যারালালিজমের Task উদাহরণগুলিতে যোগদান করা । অ্যাসিক্রোনাস Taskদৃষ্টান্ত অপেক্ষা করার জন্য এটি ব্যবহার করা বিপজ্জনক। মাইক্রোসফ্ট একটি নতুন "প্রতিশ্রুতি" প্রকার প্রবর্তন বিবেচনা করেছিল, তবে Taskপরিবর্তে বিদ্যমানটি ব্যবহার করা বেছে নিয়েছে ; অ্যাসিনক্রোনাস Taskটাস্কগুলির জন্য বিদ্যমান ধরণের পুনঃব্যবহারের ট্রেড অফ হ'ল আপনি বেশ কয়েকটি এপিআই দিয়ে শেষ করেন যা কেবল অ্যাসিঙ্ক্রোনাস কোডে ব্যবহার করা উচিত নয়।
স্টিফেন ক্লিয়ারি

12

এটি এর timeoutTaskকোনও পণ্য কিনা তা বোঝা যায় Task.Delay, যা আমি বইটিতে এটি বিশ্বাস করি।

Task.WhenAnyপ্রত্যাবর্তন Task<Task>ঘটে, যেখানে আর্গুমেন্ট হিসাবে আপনি পাস করেছেন এমন একটির অভ্যন্তরীণ কাজ। এটি আবার এভাবে লেখা যেতে পারে:

Task<Task> anyTask = Task.WhenAny(downloadTask, timeoutTask);
await anyTask;
if (anyTask.Result == timeoutTask)  
  return null;  
return downloadTask.Result; 

উভয় ক্ষেত্রেই, কারণ downloadTaskইতিমধ্যে সম্পন্ন হয়েছে, তার মাঝে একটি খুব গৌণ পার্থক্য return await downloadTaskএবং return downloadTask.ResultAggregateExceptionমন্তব্যগুলিতে @KirillShlenskiy দ্বারা নির্দেশিত অনুসারে এটি পরবর্তী যেটি কোনও আসল ব্যতিক্রমকে আবৃত করে ফেলবে। প্রাক্তনটি কেবল আসল ব্যতিক্রমটি পুনরায় নিক্ষেপ করবে।

উভয় ক্ষেত্রেই, আপনি যেখানেই ব্যতিক্রমগুলি পরিচালনা করেন AggregateExceptionনা কেন, ত্রুটির কারণটি পেতে আপনার যেকোন উপায়ে এর অভ্যন্তরীণ ব্যতিক্রমগুলি পরীক্ষা করা উচিত ।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.