কীভাবে এবং কখন 'async' এবং 'অপেক্ষা' করবেন


1064

প্রধান জিনিস আমার বোঝার এক থেকে asyncএবংawait কিন্তু ব্যবহার করা হয় তাদের ব্যাকগ্রাউন্ডে থ্রেড ডিম ছাড়ার দীর্ঘ সময়কাল যুক্তিবিজ্ঞান সঞ্চালন করতে সমান - কি সহজ লিখতে কোড করতে এবং পড়তে হয়?

আমি বর্তমানে সর্বাধিক প্রাথমিক উদাহরণ চেষ্টা করছি। আমি কিছু মন্তব্য ইনলাইন যুক্ত করেছি। আপনি আমার জন্য এটি পরিষ্কার করতে পারেন?

// I don't understand why this method must be marked as `async`.
private async void button1_Click(object sender, EventArgs e)
{
    Task<int> access = DoSomethingAsync();
    // task independent stuff here

    // this line is reached after the 5 seconds sleep from 
    // DoSomethingAsync() method. Shouldn't it be reached immediately? 
    int a = 1; 

    // from my understanding the waiting should be done here.
    int x = await access; 
}

async Task<int> DoSomethingAsync()
{
    // is this executed on a background thread?
    System.Threading.Thread.Sleep(5000);
    return 1;
}

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

উত্তর:


759

ব্যবহার করার সময় asyncএবং awaitসংকলক পটভূমিতে একটি রাষ্ট্রীয় মেশিন উত্পন্ন করে।

এখানে এমন একটি উদাহরণ যা আমি আশা করি যে আমি চলমান কিছু উচ্চ-স্তরের বিশদটি ব্যাখ্যা করতে পারি:

public async Task MyMethodAsync()
{
    Task<int> longRunningTask = LongRunningOperationAsync();
    // independent work which doesn't need the result of LongRunningOperationAsync can be done here

    //and now we call await on the task 
    int result = await longRunningTask;
    //use the result 
    Console.WriteLine(result);
}

public async Task<int> LongRunningOperationAsync() // assume we return an int from this long running operation 
{
    await Task.Delay(1000); // 1 second delay
    return 1;
}

ঠিক আছে, তাই এখানে কি ঘটে:

  1. Task<int> longRunningTask = LongRunningOperationAsync(); কার্যকর করা শুরু LongRunningOperation

  2. আসল মূল থ্রেড ধরে রাখুন (থ্রেড আইডি = 1) তারপরে স্বতন্ত্র কাজ করা হয়েছে await longRunningTask

    এখন, যদি এটি longRunningTaskশেষ না হয়ে থাকে এবং এটি এখনও চলমান থাকে তবে MyMethodAsync()তার কলিং পদ্ধতিতে ফিরে আসবে, সুতরাং মূল থ্রেডটি অবরুদ্ধ হবে না। যখন longRunningTaskতখন ThreadPool থেকে একটি থ্রেড (যে কোন থ্রেড হতে পারে) ফিরে আসবে সম্পন্ন করা হয় MyMethodAsync()তার পূর্ববর্তী প্রেক্ষাপটে এবং (কনসোলে ফলাফলের মুদ্রণ এই ক্ষেত্রে) মৃত্যুদণ্ড অবিরত।

দ্বিতীয় longRunningTaskকেসটি হ'ল ইতোমধ্যে এর কার্যকরকরণ শেষ হয়েছে এবং ফলাফল উপলব্ধ is পৌঁছানোর সময় await longRunningTaskআমাদের ইতিমধ্যে ফলাফল রয়েছে যাতে কোডটি একই থ্রেডে চালানো চালিয়ে যেতে থাকবে। (এক্ষেত্রে কনসোলের মুদ্রণের ফলাফল)। অবশ্যই এটি উপরের উদাহরণের ক্ষেত্রে নয়, যেখানে সেখানে Task.Delay(1000)জড়িত রয়েছে।


65
আমাদের কেন "টাস্ক.ডেলি (1000)" দিয়ে "অপেক্ষা" করা আছে; LongRunningOperation async পদ্ধতিতে?
বেনিসন সাম

3
@ কোডিয়া নিবন্ধটির সাথে এরিক লিপার্টের মন্তব্যে তিনি এই বিষয়টির সাথে একটি সূচনামূলক নিবন্ধ যুক্ত করেছেন যেখানে তিনি সুনির্দিষ্টভাবে এসইএনসি-ওয়েভেটের সাথে ডওভেন্টস কৌশলটির তুলনা করেছেন
ক্যামিলো মার্টিনেজ

13
@ বেনিসনস্যাম থ্রেডটি কিছুটা পুরানো তবে আমার একই প্রশ্ন ছিল এবং আমি উত্তর খুঁজছিলাম। "অপেক্ষা" করার কারণ হ'ল আমরা "অপেক্ষা" বাদ দিলে LongRunningOperationAsync () অবিলম্বে ফিরে আসবে। প্রকৃতপক্ষে সংকলকটি একটি সতর্কতা দেবে যদি আমরা অপেক্ষাটি সরিয়ে ফেলি। স্টিফেন ক্লিয়ারির ব্লগ পোস্ট ব্লগ.স্টেফেনচিলারি.কম / ২০১০ / ২০১৮ / ডিজাইনের আলোচনার একটি অনুকরণীয় দেয়।
শেলবিপিরের

70
যদি প্রতিটি অ্যাসিঙ্ক পদ্ধতির অভ্যন্তরে অপেক্ষা করা প্রয়োজন, এবং কেবল অ্যাসিঙ্কযুক্ত কোনও পদ্ধতিতে অপেক্ষা করা যেতে পারে, কখন বন্ধ হয়?
ব্রুনো স্যান্টোস

108
এই উত্তরটি স্পষ্টতই ভুল। এই অনেকগুলি upvotes অনেক ব্যবহারকারীকে ভুল বোঝার কারণ করবে। এমএস ডকুমেন্টেশন পরিষ্কারভাবে বলেছে, কেবলমাত্র এসিএনসি ব্যবহার করার সময় অন্য কোনও থ্রেড ব্যবহার করা হবে না। msdn.microsoft.com/en-us/library/mt674882.aspx দয়া করে কেউ উত্তরটি সংশোধন করুন। এই কারণে আমি একটি পুরো দিন নষ্ট।
কৃষ্ণা দীপক

171

আমার বোধগম্যতা থেকে মূল বিষয়গুলির মধ্যে একটি যা অ্যাসিঙ্ক এবং করায় অপেক্ষা করে তা হ'ল কোডটি লেখা এবং পড়া সহজ করে make

হ্যাঁ, তারা অ্যাসিঙ্ক্রোনাস কোডটি সহজেই লিখতে এবং পড়তে সহজ করে তোলে ।

দীর্ঘমেয়াদী যুক্তি সম্পাদন করার জন্য এটি ব্যাকগ্রাউন্ড থ্রেডগুলির একই জিনিস?

একদমই না.

// আমি বুঝতে পারি না কেন এই পদ্ধতিটি 'async' হিসাবে চিহ্নিত করা উচিত।

মূল asyncশব্দটি কীওয়ার্ডটি সক্ষম করে await। সুতরাং যে কোনও পদ্ধতি ব্যবহার করে awaitঅবশ্যই চিহ্নিত করতে হবে async

// এই লাইনটি DoSomethingAsync () পদ্ধতি থেকে 5 সেকেন্ডের ঘুমের পরে পৌঁছেছে। তাৎক্ষণিকভাবে পৌঁছানো উচিত নয়?

না, কারণ asyncডিফল্টরূপে পদ্ধতিগুলি অন্য থ্রেডে চালিত হয় না।

// এটি কি কোনও পটভূমির থ্রেডে মৃত্যুদন্ড কার্যকর করা হয়?

না।


আপনি আমার async/ awaitভূমিকা উপকারী হতে পারে । সরকারী দুটিই MSDN ডক্স এছাড়াও অসাধারণভাবে ভাল (বিশেষ করে হয় টোকা অধ্যায়), এবং asyncদলের একটি চমৎকার আউট করা প্রায়শই জিজ্ঞাসিত প্রশ্নাবলী


6
সুতরাং এটি কোনও পটভূমির থ্রেডে চলছে না, তবে এটি ব্লকও করে না। এটি অসিনক্রোনাস এপিআই এর কারণে সম্ভব যা থ্রেডগুলির সাথে জাগ্রত করার পরিবর্তে কলব্যাক ব্যবহার করে। আপনি একটি (I / O, সকেট, ..) অপারেশন শুরু করেন এবং আপনার জিনিসগুলি করতে ফিরে যান। অপারেশন হয়ে গেলে, ওএস কলব্যাক শুরু করবে। নোড.জেএস বা পাইথন ট্যুইস্টেড ফ্রেমওয়ার্কটি এটিই করে এবং তাদের কিছু সুন্দর ব্যাখ্যাও রয়েছে।
রোমান প্লিল

3
"অ্যাসিঙ্ক কীওয়ার্ডটি প্রতীক্ষিত কীওয়ার্ডটি সক্ষম করে So সুতরাং অপেক্ষা করার যে কোনও পদ্ধতি অবশ্যই অ্যাসিঙ্ক হিসাবে চিহ্নিত করা উচিত" ", - তবে কেন? এই উত্তরটি কেন পদ্ধতিটিকে অ্যাসিঙ্ক হিসাবে চিহ্নিত করতে হবে তা বুঝতে সহায়তা করে না। অপেক্ষার কীওয়ার্ডগুলির জন্য অভ্যন্তরটি অনুসন্ধান করে পদ্ধতিটি অ্যাসিঙ্ক হিসাবে কেবল সংকলকটি অনুমান করতে পারে না?
স্তানিস্লাভ

9
@ স্ট্যানিস্লাভ: আমার একটি ব্লগ এন্ট্রি রয়েছে যা সেই প্রশ্নটিকে সম্বোধন করে।
স্টিফেন ক্লারি

3
প্রস্তাবিত স্পষ্টতা: না, কারণ asyncপদ্ধতিগুলি অন্য থ্রেডে ডিফল্টরূপে চালিত হয় না। আপনার উদাহরণে Sleep()কলটি DoSomethingAsync()বর্তমান থ্রেডকে অবরুদ্ধ করে যা কার্যকর button1_Click()হওয়া অবধি DoSomethingAsync()সম্পূর্ণ হওয়া অবধি বাধা দেয় । নোট করুন যেThread.Sleep()Task.Delay() does not.
সঞ্চালক

166

ব্যাখ্যা

উচ্চ স্তরের async/ এর একটি দ্রুত উদাহরণ এখানে await। এর বাইরেও আরও অনেক বিশদ বিবেচনা করতে হবে।

দ্রষ্টব্য: Task.Delay(1000)1 সেকেন্ডের জন্য কাজ করার অনুকরণ করে। আমি মনে করি এটি বাহ্যিক উত্স থেকে প্রতিক্রিয়া জন্য অপেক্ষা হিসাবে ভাবা ভাল। যেহেতু আমাদের কোডটি কোনও প্রতিক্রিয়ার জন্য অপেক্ষা করছে, তাই সিস্টেমটি চলমান কার্যটিকে পাশের দিকে সেট করে এবং এটি শেষ হয়ে গেলে এটিতে ফিরে আসতে পারে। এদিকে, এটি সেই থ্রেডে আরও কিছু কাজ করতে পারে।

নীচের উদাহরণে, প্রথম ব্লক হুবহু এটি করছে। এটি সমস্ত কাজ অবিলম্বে ( Task.Delayলাইনগুলি) শুরু করে এবং এগুলি পাশের দিকে সেট করে। await aপরবর্তী লাইনে যাওয়ার আগে 1 সেকেন্ড বিলম্ব না হওয়া পর্যন্ত কোডটি লাইনে থামবে। যেহেতু b, c, d, এবং eসব প্রায় সঠিক একই সময়ে নির্বাহ শুরু a(অপেক্ষায় রয়েছেন অভাবে), তারা মোটামুটিভাবে এই ক্ষেত্রে একই সময়ে শেষ করা উচিত নয়।

নীচের উদাহরণে, দ্বিতীয় ব্লকটি একটি কাজ শুরু করছে awaitএবং পরবর্তী কাজগুলি শুরুর আগে এটি শেষ করার অপেক্ষায় রয়েছে (এটিই হয়)) এর প্রতিটি পুনরাবৃত্তির জন্য 1 সেকেন্ড সময় লাগে। awaitপ্রোগ্রাম pausing এবং চালিয়ে যাওয়ার আগে ফলাফলের জন্য অপেক্ষা করছে। এটি প্রথম এবং দ্বিতীয় ব্লকের মধ্যে প্রধান পার্থক্য।

উদাহরণ

Console.WriteLine(DateTime.Now);

// This block takes 1 second to run because all
// 5 tasks are running simultaneously
{
    var a = Task.Delay(1000);
    var b = Task.Delay(1000);
    var c = Task.Delay(1000);
    var d = Task.Delay(1000);
    var e = Task.Delay(1000);

    await a;
    await b;
    await c;
    await d;
    await e;
}

Console.WriteLine(DateTime.Now);

// This block takes 5 seconds to run because each "await"
// pauses the code until the task finishes
{
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
    await Task.Delay(1000);
}
Console.WriteLine(DateTime.Now);

আউটপুট:

5/24/2017 2:22:50 PM
5/24/2017 2:22:51 PM (First block took 1 second)
5/24/2017 2:22:56 PM (Second block took 5 seconds)

সিঙ্ক্রোনাইজেশন কনটেক্সট সম্পর্কিত অতিরিক্ত তথ্য

দ্রষ্টব্য: এখানেই জিনিসগুলি আমার জন্য কিছুটা কুয়াশাচ্ছন্ন হয়ে পড়ে, তাই যদি আমি কোনও বিষয়ে ভুল হয়ে থাকি তবে দয়া করে আমাকে সংশোধন করুন এবং আমি উত্তরটি আপডেট করব। এটি কীভাবে কাজ করে সে সম্পর্কে একটি প্রাথমিক ধারণা থাকা গুরুত্বপূর্ণ তবে আপনি যতক্ষণ না ব্যবহার করেন ততক্ষণ এ সম্পর্কে বিশেষজ্ঞ না হয়ে আপনি পেতে পারেন ConfigureAwait(false), যদিও আপনি সম্ভবত অপ্টিমাইজেশনের জন্য কিছু সুযোগ হারাবেন, আমি ধরে নিই।

এর একটি দিক রয়েছে যা ধারণাটি async/ awaitধারণাটিকে কিছুটা আঁকড়ে ধরেছে। এটাই সত্য যে এই উদাহরণে, এটি একই থ্রেডে ঘটছে (বা কমপক্ষে এটির ক্ষেত্রে একই থ্রেড হিসাবে কী প্রদর্শিত হবে SynchronizationContext)। ডিফল্টরূপে, awaitএটি চলমান মূল থ্রেডের সিঙ্ক্রোনাইজেশন প্রসঙ্গে পুনরুদ্ধার করবে। উদাহরণস্বরূপ, এএসপি.এনইটিটিতে HttpContextকোনও অনুরোধ এলে আপনার সাথে এটি থ্রেডের সাথে আবদ্ধ থাকে This আপনি যদি কোনও কিছু প্রক্রিয়াজাতকরণের মাধ্যমে থ্রেডগুলি অর্ধেক করে স্যুইচ করেন তবে আপনি এই বিষয়বস্তু থেকে আলাদা করে কোনও তথ্য বের করার চেষ্টা করতে পারেনHttpContextযা বিপর্যয়কর হতে পারে। আপনি যদি জানেন যে আপনি কোনও কিছুর জন্য প্রসঙ্গটি ব্যবহার করবেন না, আপনি এটি সম্পর্কে "যত্ন না করা" বেছে নিতে পারেন। এটি মূলত আপনার কোডটিকে প্রসঙ্গটি এনে না দিয়েই একটি পৃথক থ্রেডে চালানোর অনুমতি দেয়।

আপনি কীভাবে এটি অর্জন করবেন? ডিফল্টরূপে, await a;কোডটি আসলে একটি ধারণা তৈরি করছে যে আপনি প্রসঙ্গটি ক্যাপচার এবং পুনরুদ্ধার করতে চান না:

await a; //Same as the line below
await a.ConfigureAwait(true);

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

await a.ConfigureAwait(false);

প্রোগ্রামটি বিরতি দেওয়ার পরে, এটি সম্পূর্ণ ভিন্ন থ্রেডে একটি ভিন্ন প্রসঙ্গ সহ সম্ভাব্যভাবে চলতে থাকবে । এখান থেকেই পারফরম্যান্সের উন্নতি হবে - এটি শুরু হওয়া মূল প্রসঙ্গে পুনরুদ্ধার না করে যে কোনও উপলব্ধ থ্রেডে চালিয়ে যেতে পারে।

এই জিনিস গুলিয়ে ফেলছে? হ্যাঁ! আপনি কি এটা ধরতে পেরেছেন? সম্ভবত! একবার আপনার ধারণাগুলি উপলব্ধি হয়ে উঠলে, তারপরে স্টিফেন ক্লিয়ারির ব্যাখ্যাগুলিতে এগিয়ে যান যা async/ awaitইতিমধ্যে কারিগরি বোঝার সাথে কারও প্রতি বেশি আগ্রহী হয় ।


আসুন বলুন যে এই সমস্ত টাস্কটি যদি কোন পূর্বে ফিরে আসে এবং আমি যদি প্রথম টাস্কের ফলাফলটি দ্বিতীয় টাস্কে ব্যবহার করি (বা কিছু গণনা) এটি ভুল হবে?
বীরেন্দ্র গুপ্ত

3
@ বীরেন্দ্রগুপ্ত হ্যাঁ আপনি সচেতনভাবে সে ক্ষেত্রে অবিচ্ছিন্নভাবে চালনা না করা পছন্দ করবেন (কারণ তারা অবিচ্ছিন্ন নয়)। কনফিগারেশন প্রসঙ্গে যা আমি এখানে যাব না সে সম্পর্কে উপলব্ধি করতে আরও কয়েকটি জিনিস রয়েছে
জো ফিলিপস

তাহলে await MethodCall()কি পরম অপচয়? আপনি পাশাপাশি await/ ড্রপ করতে পারে async?
বিতানি

2
পছন্দ করেছেন আপনি যখন ফোন করবেন তখন awaitআমার মনে হয় এটি থ্রেডটি ধরে রাখার পরিবর্তে পুলটিতে ছেড়ে দেয়। টাস্কের ফেরার অপেক্ষার সময় এটি অন্য কোথাও ব্যবহারের জন্য উপলব্ধ করে তোলে
জো ফিলিপস

2
@ জোফিলিপস আমি মনে করি আপনি যা বলেছিলেন তা হ'ল আসিঙ্ক / প্রতীক্ষার মূলমন্ত্র। কলিং থ্রেডটি মুক্ত হয়েছে এবং মেশিনের অন্যান্য প্রক্রিয়াগুলি দ্বারা এটি ব্যবহার করা যেতে পারে। অপেক্ষার কলটি সম্পূর্ণ হলে, কলার মূলত কী শুরু হয়েছিল তা আবার শুরু করতে একটি নতুন থ্রেড ব্যবহৃত হয়। কলকারী এখনও অপেক্ষা করছে, তবে সুবিধাটি হ'ল এর মধ্যে একটি থ্রেড মুক্ত হয়েছে। এ্যাসাইক / ওয়েট এর সুবিধা কি?
বব হর্ন

147

অন্যান্য উত্তরগুলির জন্য আরও অপেক্ষা করুন (সি # রেফারেন্স)

এবং আরও সুনির্দিষ্টভাবে অন্তর্ভুক্ত উদাহরণটিতে, এটি আপনার পরিস্থিতিটি কিছুটা ব্যাখ্যা করে

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

private async void button1_Click(object sender, EventArgs e)
{
    // Call the method that runs asynchronously.
    string result = await WaitAsynchronouslyAsync();

    // Call the method that runs synchronously.
    //string result = await WaitSynchronously ();

    // Display the result.
    textBox1.Text += result;
}

// The following method runs asynchronously. The UI thread is not
// blocked during the delay. You can move or resize the Form1 window 
// while Task.Delay is running.
public async Task<string> WaitAsynchronouslyAsync()
{
    await Task.Delay(10000);
    return "Finished";
}

// The following method runs synchronously, despite the use of async.
// You cannot move or resize the Form1 window while Thread.Sleep
// is running because the UI thread is blocked.
public async Task<string> WaitSynchronously()
{
    // Add a using directive for System.Threading.
    Thread.Sleep(10000);
    return "Finished";
}

3
উত্তরের জন্য ধন্যবাদ. তবে কী ওয়েটআসিনক্রোনারসঅ্যাসেন্স () পৃথক থ্রেডে মৃত্যুদন্ড কার্যকর করা হবে?
ড্যান দিনু

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

13
এই এমএসডিএন নিবন্ধ অনুসারে , "অ্যাসিঙ্ক এবং অপেক্ষার কীওয়ার্ডগুলির কারণে অতিরিক্ত থ্রেড তৈরি হওয়ার কারণ হয় না ... একটি অ্যাসিঙ্ক পদ্ধতিটি তার নিজস্ব থ্রেডে চলবে না"। আমার উপলব্ধি হ'ল কীওয়ার্ডগুলির অপেক্ষায় দীর্ঘতর ক্রিয়াকলাপ শেষ হওয়ার অপেক্ষায় সমস্ত সম্ভাব্য স্বতন্ত্র কোডটি চালানোর অনুমতি দেওয়ার জন্য ফ্রেমওয়ার্কটি এগিয়ে যায় (কলারের কাছে ফিরে যায়)। আমি মনে করি এর অর্থ হ'ল একবার সমস্ত স্বতন্ত্র কোড চলে গেলে, দীর্ঘ অপারেশনটি যদি ফিরে না আসে তবে এটি ব্লক হয়ে যাবে। যদিও আমি এখন এটি শিখছি।
Vimes

9
পছন্দ করুন এটি অন্য কোনও থ্রেডে কার্যকর হয় না । টাইমার যখন Task.Delayআগুনের দ্বারা ব্যবহৃত হয় তখন এটি কেবল ধারাবাহিকতা (বাকি পদ্ধতিটি) কল করার সময়সূচি দেয় ।
MgSam

1
ঘুমের কারণে এই উত্তরটি ভুল। প্রত্যাশিত টাস্ক সহ গৃহীত উত্তরটি দেখুন eডেলা (1000); যার সঠিক আচরণ রয়েছে।
জারেড আপডেটিকে

62

একটি সাধারণ কনসোল প্রোগ্রামে উপরোক্ত ব্যাখ্যাগুলি ক্রিয়াতে দেখানো হচ্ছে:

class Program
{
    static void Main(string[] args)
    {
        TestAsyncAwaitMethods();
        Console.WriteLine("Press any key to exit...");
        Console.ReadLine();
    }

    public async static void TestAsyncAwaitMethods()
    {
        await LongRunningMethod();
    }

    public static async Task<int> LongRunningMethod()
    {
        Console.WriteLine("Starting Long Running method...");
        await Task.Delay(5000);
        Console.WriteLine("End Long Running method...");
        return 1;
    }
}

এবং আউটপুটটি হ'ল:

Starting Long Running method...
Press any key to exit...
End Long Running method...

সুতরাং,

  1. মাইনের মাধ্যমে দীর্ঘ চলমান পদ্ধতিটি শুরু হয় TestAsyncAwaitMethods। এটি তাত্ক্ষণিকভাবে বর্তমান থ্রেডটি থামিয়ে না দিয়ে ফিরে আসে এবং আমরা তাত্ক্ষণিকভাবে 'বার বার প্রস্থান করতে কোনও কী চাপুন' দেখি see
  2. এই সমস্ত সময়, LongRunningMethodপটভূমি চলমান। এটি শেষ হয়ে গেলে থ্রেডপুলের আর একটি থ্রেড এই প্রসঙ্গটি তুলে নিয়ে চূড়ান্ত বার্তাটি প্রদর্শন করে

সুতরাং, থ্রেড ব্লক করা হয় না।


"প্রস্থান করার জন্য কোনও কী টিপুন ..." আউটপুটটির কোন অংশে প্রদর্শিত হবে?
স্টুডিওক্স

1
এবং (1 রিটার্ন) এর ব্যবহার কী? এটা দরকারি?
স্টুডিওক্স

1
@ স্টুডিওক্স আমি মনে করি এটির অবশ্যই রিটার্ন টাইপ পূর্ণসংখ্যা থাকতে হবে
কুবা ডু

আমি মনে করি এই return 1অংশটি আরও কিছু ব্যাখ্যাের দাবি রাখে: awaitকীওয়ার্ডটি আপনাকে অন্তর্নিহিত প্রকারের Task<T>প্রত্যক্ষভাবে সরাসরি ফেরত দিতে দেয় , সুতরাং আপনার প্রস্থানিত কোডটি অপেক্ষার / অ্যাসিঙ্ক ওয়ার্ল্ডের সাথে মানিয়ে নেওয়া সহজ করে তোলে । তবে আপনাকে কোনও মান ফেরত দিতে হবে না , কারণ Taskকোনও রিটার্নিং টাইপ নির্দিষ্ট না করেই কোনও ফেরত পাওয়া সম্ভব , যা সিঙ্ক্রোনাস voidপদ্ধতির সমতুল্য । মনে রাখবেন যে সি # async voidপদ্ধতিগুলিকে মঞ্জুরি দেয় তবে আপনি ইভেন্ট হ্যান্ডলারদের মোকাবেলা না করা অবধি আপনার এড়ানো উচিত।
ক্রিশ্চিয়ানো কিস

41

আমি মনে করি আপনি এর সাথে একটি খারাপ উদাহরণ বেছে নিয়েছেন System.Threading.Thread.Sleep

কোনও asyncটাস্কের পয়েন্ট হ'ল এটিকে মূল থ্রেড লক না করে পটভূমিতে সম্পাদন করা suchDownloadFileAsync

System.Threading.Thread.Sleep "সম্পন্ন হচ্ছে" এমন কিছু নয়, এটি কেবল ঘুমায় এবং তাই আপনার পরবর্তী লাইনটি 5 সেকেন্ড পরে পৌঁছে যায় ...

এই নিবন্ধটি পড়ুন, আমি মনে করি এটি একটি দুর্দান্ত ব্যাখ্যা asyncএবং awaitধারণার: http://msdn.microsoft.com/en-us/library/vstudio/hh191443.aspx


3
ঘুম কেন খারাপ উদাহরণ তবে ডাউনলোড ভাল উদাহরণ। থ্রেডটি দেখলে এটি ফুবার জাতীয় জিনিসটির মতো হয় leep ঘুমান আমি বুঝতে পারি যে কিছু সময় আছে। আমি মনে করি তার প্রশ্নটি প্রাসঙ্গিক
আব্দুররহিম

1
@ আবদুররাহীম থ্রেডটি Thread.Sleepব্লক করে (থ্রেড অলস বসে থাকা ছাড়া অন্য কিছু করতে পারে না), তবে একটি অ্যাসিঙ্ক পদ্ধতি এটি করে না। এর ক্ষেত্রে DownloadFileAsync, রিমোট সার্ভার থেকে কোনও উত্তর না আসা পর্যন্ত থ্রেডটি গিয়ে অন্য কিছু করতে পারে। Task.Delayঅ্যাসিঙ্ক পদ্ধতিতে "কিছু সময় লাগে এমন" এর জন্য আরও ভাল স্থানধারক , যেহেতু এটি আসলে অ্যাসিনক্রোনাস।
গ্যাব্রিয়েল লুসি

@ গ্যাব্রিয়েললুচি আমার আপত্তিটি বিলম্ব বনাম ঘুম সম্পর্কে নয়; আপনার উত্তরটি আরও বেশি খড়ের জবাবের মতো দেখাচ্ছে; যদি আপনি এই প্রশ্নের একটি মন্তব্য হিসাবে রাখেন যে আমি আপত্তি করতে পারি না তবে উত্তর হিসাবে এটি স্ট্রোম্যানের উত্তরের মতো আরও গন্ধ পাচ্ছে। আমি মনে করি যে সেখানে অ্যাসিঙ্কটি ব্যবহার করা এখনও ঠিক আছে এমনকি তার যে সমস্ত কল করতে হবে সেগুলি কলগুলি অবরুদ্ধ করে দেবে; এটি সমস্ত উদ্দেশ্যকে অকার্যকর করবে না ... এমনকি সমস্ত বামটি সিনট্যাকটিক চিনিও এটি একটি বৈধ ক্ষেত্রে হিসাবে গণ্য হবে,
আব্দুররাহিম

1
এটা আমার উত্তর ছিল না। তবে আপনার বক্তব্য সম্বোধন করার জন্য: এটি পদ্ধতির উদ্দেশ্যগুলির উপর নির্ভর করে। তিনি যদি কেবল কল করার জন্য একটি পদ্ধতি চান তবে তিনি সফল হন। তবে এক্ষেত্রে তিনি এমন একটি পদ্ধতি তৈরি করতে চাইছিলেন যা অবিচ্ছিন্নভাবে চালিত হয়। তিনি কেবল asyncকীওয়ার্ড ব্যবহার করে তা করেছিলেন । তবে তার পদ্ধতিটি এখনও সুসংগতভাবে চলছিল, এবং এই উত্তরটি পুরোপুরি ব্যাখ্যা করেছিল যে কেন: কারণ তিনি আসলে কোনও অ্যাসিনক্রোনাস কোড চালাতেন না। চিহ্নিত হিসাবে চিহ্নিত পদ্ধতিগুলি asyncআপনার awaitঅসম্পূর্ণ হওয়া অবধি সমকালীনভাবে চলতে থাকে Task। যদি সেখানে না থাকে await, তবে পদ্ধতিটি সিঙ্ক্রোনিকভাবে চলবে এবং সংকলক আপনাকে সে সম্পর্কে সতর্ক করবে।
গ্যাব্রিয়েল লুসি

23

যারা অনুসরণ করেন তাদের কাছে এটি পরিষ্কার করার জন্য একটি দ্রুত কনসোল প্রোগ্রাম রয়েছে। TaskToDoপদ্ধতি আপনার দীর্ঘ চলমান পদ্ধতি আপনি ASYNC করতে চাই হয়। এ্যাসিঙ্ক রান চালানো TestAsyncপদ্ধতি দ্বারা সম্পন্ন হয় । পরীক্ষার লুপগুলি কেবল TaskToDoকার্যগুলির মধ্য দিয়ে চলে এবং এ্যাসিঙ্ক চালায়। আপনি ফলাফলগুলিতে দেখতে পাচ্ছেন যেহেতু তারা রান থেকে রান করতে একই ক্রমে সম্পূর্ণ না করে - তারা সম্পূর্ণ করার পরে কনসোল ইউআই থ্রেডকে প্রতিবেদন করছে। সরলবাদী, তবে আমি মনে করি সরল উদাহরণগুলি আরও জড়িত উদাহরণগুলির চেয়ে ভালভাবে প্যাটার্নটির মূলটি বের করে:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace TestingAsync
{
    class Program
    {
        static void Main(string[] args)
        {
            TestLoops();
            Console.Read();
        }

        private static async void TestLoops()
        {
            for (int i = 0; i < 100; i++)
            {
                await TestAsync(i);
            }
        }

        private static Task TestAsync(int i)
        {
            return Task.Run(() => TaskToDo(i));
        }

        private async static void TaskToDo(int i)
        {
            await Task.Delay(10);
            Console.WriteLine(i);
        }
    }
}

20

দ্রুত শিখার জন্য ..

  • পদ্ধতি নির্বাহের প্রবাহটি (একটি চিত্র সহ) বুঝতে: 3 মিনিট

  • প্রশ্ন অন্তঃকরণ (শেখার জন্য): 1 মিনিট

  • সিনট্যাক্স চিনির মাধ্যমে দ্রুত পান: 5 মিনিট

  • একজন বিকাশকারীর বিভ্রান্তি ভাগ করুন: 5 মিনিট

  • সমস্যা: দ্রুত অ্যাসিঙ্ক কোড: 2 মিনিট স্বাভাবিক কোডের একটি বাস্তব-বিশ্বের বাস্তবায়ন পরিবর্তন করুন

  • এখন কোথায়?

পদ্ধতি নির্বাহের প্রবাহটি (একটি চিত্র সহ) বুঝতে: 3 মিনিট

এই চিত্রটিতে, কেবলমাত্র # 6 এ ফোকাস করুন (আরও কিছু নয়) এখানে চিত্র বর্ণনা লিখুন

# Step ধাপে: কাজ শেষ হয়ে গেছে বলে এখানে কার্যকর করা বন্ধ হয়ে গেছে। চালিয়ে যেতে এর জন্য getStringTask (কোনও ফাংশনের ধরণ) থেকে ফলাফল দরকার। সুতরাং, awaitএটির অগ্রগতি স্থগিত করার জন্য এবং একজন কলকারীকে নিয়ন্ত্রণ ফিরিয়ে (ফলন) দেওয়ার জন্য (আমরা এই পদ্ধতির মধ্যে আছি) এটি অপারেটর ব্যবহার করে । GetStringTask- এ আসল কলটি আগে # 2 এ হয়েছিল। # 2 এ একটি স্ট্রিং ফলাফল ফেরত দেওয়ার প্রতিশ্রুতি দেওয়া হয়েছিল। তবে ফলাফল কখন ফিরিয়ে দেবে? আমাদের কি (# 1: এক্সেস দ্য ওয়েবেএেন্সিক) আবার ২ য় কল করা উচিত? ফলাফলটি কে পেয়েছে, # 2 (কলিং স্টেটমেন্ট) বা # 6 (বিবৃতিটির অপেক্ষায়)

এক্সেস দ্য ওয়েবেএেন্সিক () এর বাহ্যিক কলারও এখন অপেক্ষা করছে। সুতরাং কলার অ্যাক্সেস দ্য ওয়েবেএেন্সিকের জন্য অপেক্ষা করছে এবং এই মুহুর্তে অ্যাক্সেস দ্য ওয়েবেএসিঙ্ক অপেক্ষা করছে স্টেটআরসিএনসিঙ্কের জন্য। মজার বিষয় হ'ল অ্যাক্সেস দ্য ওয়েবেএেন্সেক অপেক্ষা করার আগে সময় বাঁচানোর জন্য অপেক্ষা (# 4) করার আগে কিছু কাজ করেছিল। মাল্টিটাস্কে একই স্বাধীনতা বহিরাগত কলার (এবং চেইনের সমস্ত কলার) এর জন্যও উপলব্ধ এবং এটি এই 'অ্যাসিঙ্ক' জিনিসটির বৃহত্তম প্লাস! আপনার কাছে মনে হচ্ছে এটি সিঙ্ক্রোনাস..আর স্বাভাবিক তবে এটি হয় না।

মনে রাখবেন, পদ্ধতিটি ইতিমধ্যে ফিরে এসেছিল (# 2), এটি আর ফিরে আসতে পারে না (দ্বিতীয়বার নয়)। তাহলে কলকারী কীভাবে জানতে পারবে? এটি সবই টাস্ক সম্পর্কে ! টাস্ক পাস হয়েছিল। কার্যটির জন্য অপেক্ষা করা হয়েছিল (পদ্ধতি নয়, মান নয়)। টাস্কে মান নির্ধারণ করা হবে। কার্য স্থিতি সম্পূর্ণ করতে সেট করা হবে। কলার কেবল টাস্ক (# 6) পর্যবেক্ষণ করে। 6 / # উত্তরটি কোথায় / কে ফলাফল পায় তার উত্তর। আরও পরে এখানে পড়ুন

শেখার জন্য প্রশ্ন অন্তঃকরণ: 1 মিনিট

আসুন প্রশ্নটি কিছুটা সামঞ্জস্য করুন:

কিভাবে এবং কখন ব্যবহার করবেন এবং ? asyncawait Tasks

কারণ শেখা Taskস্বয়ংক্রিয়ভাবে অন্য দুটি কভার করে (এবং আপনার প্রশ্নের উত্তর দেয়)

সিনট্যাক্স চিনির মাধ্যমে দ্রুত পান: 5 মিনিট

  • রূপান্তর করার আগে (মূল পদ্ধতি)

    internal static int Method(int arg0, int arg1) { int result = arg0 + arg1; IO(); // Do some long running IO. return result; }

  • উপরের পদ্ধতিটি কল করার জন্য একটি টাস্ক-আইয়েড পদ্ধতি

    internal static Task<int> MethodTask(int arg0, int arg1) { Task<int> task = new Task<int>(() => Method(arg0, arg1)); task.Start(); // Hot task (started task) should always be returned. return task; }

আমরা কি অপেক্ষা বা অ্যাসিঙ্ক উল্লেখ করেছি? না। উপরের পদ্ধতিটি কল করুন এবং আপনি একটি টাস্ক পান যা আপনি নিরীক্ষণ করতে পারেন। আপনি ইতিমধ্যে জানেন যে টাস্কটি কী দেয় ... একটি পূর্ণসংখ্যা।

  • কোনও টাস্ককে কল করা কিছুটা মুশকিল এবং যখন কীওয়ার্ডগুলি প্রদর্শিত শুরু হয় appear আসুন মেথডটাস্ক ()

    internal static async Task<int> MethodAsync(int arg0, int arg1) { int result = await HelperMethods.MethodTask(arg0, arg1); return result; }

উপরের একই কোডটি নীচের চিত্র হিসাবে যুক্ত হয়েছে: এখানে চিত্র বর্ণনা লিখুন

  1. আমরা 'অপেক্ষার' কাজটি শেষ হওয়ার জন্য। অত: পরawait
  2. যেহেতু আমরা প্রতীক্ষা ব্যবহার করি তাই আমাদের অবশ্যই ব্যবহার করতে হবে async(বাধ্যতামূলক সিনট্যাক্স)
  3. Asyncউপসর্গ হিসাবে কোড পদ্ধতিতে সিঙ্ক করুন (কোডিং স্ট্যান্ডার্ড)

awaitবুঝতে সহজ তবে বাকি দুটি ( async, Async) নাও থাকতে পারে :)। ঠিক আছে, যদিও এটি সংকলকটির কাছে আরও অনেক কিছু বোঝা উচিত Fএর জন্য পরে এখানে পড়ুন

সুতরাং 2 অংশ আছে।

  1. 'টাস্ক' তৈরি করুন
  2. টাস্কটি কল করতে সিনট্যাকটিক চিনি তৈরি করুন ( await+async)

মনে রাখবেন, অ্যাক্সেস দ্য ওয়েলবায়েন্সিক () এর জন্য আমাদের একটি বাহ্যিক কলার ছিল এবং সেই কলারটিকেও রেহাই দেওয়া যায় না ... অর্থাৎ এটিরও এটির প্রয়োজন await+async। এবং শৃঙ্খলা অব্যাহত আছে। তবে সর্বদা Taskএক প্রান্তে থাকবে।

ঠিক আছে, তবে একজন বিকাশকারী # 1 (টাস্ক) অনুপস্থিত দেখে অবাক হয়েছেন ...

একজন বিকাশকারীর বিভ্রান্তি ভাগ করুন: 5 মিনিট

একজন বিকাশকারী বাস্তবায়ন না করার ভুল করেছে Taskতবে এটি এখনও কার্যকর হয় ! প্রশ্নটি বোঝার চেষ্টা করুন এবং এখানে প্রদত্ত কেবল স্বীকৃত উত্তর । আশা করি আপনি পড়েছেন এবং পুরোপুরি বুঝতে পেরেছেন। সংক্ষিপ্তসারটি হ'ল আমরা 'টাস্ক' দেখতে বা প্রয়োগ করতে পারি না তবে এটি কোনও অভিভাবক শ্রেণিতে কোথাও প্রয়োগ করা হয়। তেমনিভাবে আমাদের উদাহরণটিতে ইতিমধ্যে নির্মিত বলে কল MethodAsync()করা একটি Task( MethodTask()) আওয়ারফুলের সাথে সেই পদ্ধতিটি প্রয়োগ করার চেয়ে সহজ । বেশিরভাগ বিকাশকারীকে Tasksএকটি কোডকে অ্যাসিঙ্ক্রোনাসে রূপান্তর করার সময় মাথা ঘুরে বেড়াতে অসুবিধা হয় ।

টিপ: অসুবিধা আউটসোর্স করার জন্য একটি বিদ্যমান এসিঙ্ক বাস্তবায়ন (যেমন MethodAsyncবা ToListAsync) সন্ধান করার চেষ্টা করুন । সুতরাং আমাদের কেবল অ্যাসিঙ্কের সাথে ডিল করতে হবে এবং অপেক্ষা করতে হবে (এটি সহজ এবং সাধারণ কোডের সাথে বেশ সমান)

সমস্যা: দ্রুত অ্যাসিঙ্ক অপারেশনে সাধারণ কোডের বাস্তব-বাস্তবায়ন পরিবর্তন করুন: 2 মিনিট

ডেটা লেয়ারের নীচে দেখানো কোড লাইনটি ভেঙে যেতে শুরু করেছে (অনেকগুলি স্থান)। কারণ আমরা .NET ফ্রেমওয়ার্ক 4.2। * থেকে। নেট কোর থেকে আমাদের কিছু কোড আপডেট করেছি। আমাদের পুরো অ্যাপ্লিকেশন জুড়ে 1 ঘন্টার মধ্যে এটি ঠিক করতে হয়েছিল!

var myContract = query.Where(c => c.ContractID == _contractID).First();

সহজ কিছু!

  1. আমরা এন্টিফ্রেমওয়ার্ক নুগেট প্যাকেজটি ইনস্টল করেছি কারণ এটিতে ক্যুরিয়েবল এক্সটেনশন রয়েছে। বা অন্য কথায় এটি অ্যাসিঙ্ক বাস্তবায়ন (টাস্ক) করে, তাই আমরা সহজ Asyncএবং awaitকোড সহ বেঁচে থাকতে পারি ।
  2. নেমস্পেস = মাইক্রোসফ্ট.এনটিটি ফ্রেমওয়ার্ককোর

কলিং কোড লাইন এর মত বদলে গেল

var myContract = await query.Where(c => c.ContractID == _contractID).FirstAsync();
  1. পদ্ধতি স্বাক্ষর থেকে পরিবর্তিত হয়েছে

    Contract GetContract(int contractnumber)

    প্রতি

    async Task<Contract> GetContractAsync(int contractnumber)

  2. কলিং পদ্ধতিটিও প্রভাবিত GetContractAsync(123456);হয়েছিল : হিসাবে বলা হয়েছিলGetContractAsync(123456).Result;

  3. আমরা 30 মিনিটের মধ্যে এটিকে সর্বত্র পরিবর্তন করেছি!

কিন্তু স্থপতি আমাদের কেবল এটির জন্য এন্টি ফ্রেমওয়ার্ক লাইব্রেরি ব্যবহার না করার জন্য বলেছিলেন! ওহো! নাটক! তারপরে আমরা একটি কাস্টম টাস্ক বাস্তবায়ন করেছি (ইউক)। যা আপনি জানেন কিভাবে। তবুও সহজ! .. এখনও ইউক ..

এখন কোথায়? এএসপি.নেট কোর-এ সিঙ্ক্রোনাস কলগুলি অ্যাসিঙ্ক্রোনাসে রূপান্তর করার বিষয়ে আমরা দেখতে পেলাম একটি দুর্দান্ত দ্রুত ভিডিও রয়েছে , সম্ভবত এটি পড়ার পরে যে দিকে যেতে পারে সম্ভবত।


দুর্দান্ত উত্তর! এটি আমাকে একটি টন সাহায্য করেছে
cklimowski

1
চমৎকার উত্তর. আপনি কেবল কয়েকটি ছোট ছোট জিনিস ঠিক করতে চাইতে পারেন: (ক) "। নেট ফ্রেমওয়ার্ক 4.2" (আমি জানি যে এরূপ কোনও সংস্করণ নেই, বিদ্যমান) (খ) এন্টিফ্রেম ওয়ার্ক => এন্টিফ্রেমওয়ার্ক
ইমিটাইটেভ

15

এখানে সমস্ত উত্তর ব্যবহার করুন Task.Delay()বা asyncফাংশনে অন্তর্নির্মিত অন্য কিছু । তবে এখানে আমার উদাহরণ যা এই asyncফাংশনগুলির কোনওটিই ব্যবহার করে না :

// Starts counting to a large number and then immediately displays message "I'm counting...". 
// Then it waits for task to finish and displays "finished, press any key".
static void asyncTest ()
{
    Console.WriteLine("Started asyncTest()");
    Task<long> task = asyncTest_count();
    Console.WriteLine("Started counting, please wait...");
    task.Wait(); // if you comment this line you will see that message "Finished counting" will be displayed before we actually finished counting.
    //Console.WriteLine("Finished counting to " + task.Result.ToString()); // using task.Result seems to also call task.Wait().
    Console.WriteLine("Finished counting.");
    Console.WriteLine("Press any key to exit program.");
    Console.ReadLine();
}

static async Task<long> asyncTest_count()
{
    long k = 0;
    Console.WriteLine("Started asyncTest_count()");
    await Task.Run(() =>
    {
        long countTo = 100000000;
        int prevPercentDone = -1;
        for (long i = 0; i <= countTo; i++)
        {
            int percentDone = (int)(100 * (i / (double)countTo));
            if (percentDone != prevPercentDone)
            {
                prevPercentDone = percentDone;
                Console.Write(percentDone.ToString() + "% ");
            }

            k = i;
        }
    });
    Console.WriteLine("");
    Console.WriteLine("Finished asyncTest_count()");
    return k;
}

2
ধন্যবাদ! প্রথম উত্তর যা অপেক্ষা করার পরিবর্তে কিছু কাজ করে।
জেফনেল

দেখানোর জন্য আপনাকে ধন্যবাদ task.Wait();এবং কীভাবে এটি async এড়াতে / জাহান্নামের জন্য অপেক্ষা করা যেতে পারে: পি
এনকোডার

12

এই উত্তরের লক্ষ্য ASP.NET- র নির্দিষ্ট কিছু তথ্য সরবরাহ করা।

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

http://www.asp.net/mvc/tutorials/mvc-4/using-asynchronous-methods-in-aspnet-mvc-4

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


12

অ্যাসিঙ্ক এবং অপেক্ষার সহজ ব্যাখ্যা

সরল সাদৃশ্য

কোনও ব্যক্তি তাদের সকালের ট্রেনের জন্য অপেক্ষা করতে পারে । এটি বর্তমানে তারা যা করছে এটি তাদের প্রাথমিক কাজ যা তারা বর্তমানে সম্পাদন করছে। (সিঙ্ক্রোনাস প্রোগ্রামিং (আপনি সাধারণত কী করেন!))

অন্য একজন ব্যক্তি তাদের সকালের ট্রেনের জন্য অপেক্ষা করতে পারেন যখন তারা সিগারেট পান করেন এবং তারপরে তাদের কফি পান করেন। (অ্যাসিনক্রোনাস প্রোগ্রামিং)

অ্যাসিক্রোনাস প্রোগ্রামিং কী?

অ্যাসিঙ্ক্রোনাস প্রোগ্রামিং হ'ল যেখানে প্রোগ্রামার তার কোডের কয়েকটি চালানোর জন্য মৃত্যুদন্ডের মূল থ্রেড থেকে আলাদা থ্রেডে বেছে নেবে এবং তারপরে এটি সম্পূর্ণ হওয়ার পরে মূল থ্রেডকে অবহিত করবে।

অ্যাসিঙ্ক কীওয়ার্ডটি আসলে কী করে?

Async কীওয়ার্ডটিকে কোনও পদ্ধতির নামের মতো উপসর্গ করা

async void DoSomething(){ . . .

অ্যাসিঙ্ক্রোনাস টাস্কগুলিতে কল করার সময় প্রোগ্রামারকে অপেক্ষার কীওয়ার্ডটি ব্যবহার করার অনুমতি দেয়। এটিই তাই করে।

ইহা কেন গুরুত্বপূর্ণ?

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

আপনি কখন অ্যাসিঙ্ক এবং অ্যাওয়েট ব্যবহার করবেন?

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

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

আমাদের আবহাওয়াটি পেতে নেটওয়ার্কে প্রতি 5 সেকেন্ডের মধ্যে পোলিং কলগুলির জন্য অপেক্ষা করা উচিত, কারণ আবেদনকারীর ব্যবহারকারীর সুন্দর ছবি আঁকার জন্য মোবাইল টাচ স্ক্রিনের সাথে যোগাযোগ রাখা প্রয়োজন।

আপনি কীভাবে অ্যাসিঙ্ক এবং অ্যাওয়েট ব্যবহার করবেন

উপরের উদাহরণটি অনুসরণ করে, এটি কীভাবে লিখতে হবে তার কয়েকটি সিউডো কোড এখানে দেওয়া হয়েছে:

    //ASYNCHRONOUS
    //this is called using the await keyword every 5 seconds from a polling timer or something.

    async Task CheckWeather()
    {
        var weather = await GetWeather();
        //do something with the weather now you have it
    }

    async Task<WeatherResult> GetWeather()
    {

        var weatherJson = await CallToNetworkAddressToGetWeather();
        return deserializeJson<weatherJson>(weatherJson);
    }

    //SYNCHRONOUS
    //This method is called whenever the screen is pressed
    void ScreenPressed()
    {
        DrawSketchOnScreen();
    }

অতিরিক্ত নোট - আপডেট

আমি আমার মূল নোটগুলিতে উল্লেখ করতে ভুলে গেছি যে সি # তে আপনি কেবল টাস্কগুলিতে আবৃত পদ্ধতিগুলির জন্য অপেক্ষা করতে পারেন। উদাহরণস্বরূপ আপনি এই পদ্ধতির জন্য অপেক্ষা করতে পারেন:

// awaiting this will return a string.
// calling this without await (synchronously) will result in a Task<string> object.
async Task<string> FetchHelloWorld() {..

আপনি এমন পদ্ধতিগুলির জন্য অপেক্ষা করতে পারবেন না যা এই জাতীয় কাজ নয়:

async string FetchHelloWorld() {..

এখানে টাস্ক ক্লাসের উত্স কোডটি নির্দ্বিধায় নির্দ্বিধায় محسوس করুন


4
এটি লেখার জন্য সময় দেওয়ার জন্য ধন্যবাদ।
প্রশান্ত

10

অ্যাসিঙ্ক / অ্যাওয়েট

প্রকৃতপক্ষে অ্যাসিঙ্ক / অ্যাওয়েট এমন এক কীওয়ার্ড যা কেবলমাত্র একটি অ্যাসিঙ্ক্রোনাস টাস্কের কলব্যাক তৈরির জন্য সিনট্যাকটিক চিনি।

উদাহরণস্বরূপ এই অপারেশন:

    public static void DoSomeWork()
    {
        var task = Task.Run(() =>
        {
            // [RUNS ON WORKER THREAD]

            // IS NOT bubbling up due to the different threads
            throw new Exception();
            Thread.Sleep(2000);

            return "Hello";
        });

        // This is the callback
        task.ContinueWith((t) => {
            // -> Exception is swallowed silently
            Console.WriteLine("Completed");

            // [RUNS ON WORKER THREAD]
        });
    }

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

    public async static void DoSomeWork()
    {
        var result = await Task.Run(() =>
        {
            // [RUNS ON WORKER THREAD]

            // IS bubbling up
            throw new Exception();
            Thread.Sleep(2000);

            return "Hello";
        });

        // every thing below is a callback 
        // (including the calling methods)

        Console.WriteLine("Completed");

    }

অ্যাওয়েট কলগুলি অ্যাসিঙ্ক পদ্ধতিতে থাকতে হবে। এর কিছু সুবিধা রয়েছে:

  • টাস্কের ফলাফল প্রদান করে
  • স্বয়ংক্রিয়ভাবে একটি কলব্যাক তৈরি করে
  • ত্রুটিগুলির জন্য পরীক্ষা করে এবং তাদের কলস্ট্যাকে বুদবুদ করতে দেয় (কলস্ট্যাকে কেবল অপেক্ষারত কলগুলি অবধি)
  • ফলাফলের জন্য অপেক্ষা করে
  • মূল থ্রেড মুক্ত
  • মূল থ্রেডে কলব্যাক চালায়
  • কাজের জন্য থ্রেডপুল থেকে কর্মী থ্রেড ব্যবহার করে
  • কোডটি পড়া সহজ করে তোলে
  • এবং আরো অনেক কিছু

দ্রষ্টব্য : অ্যাসিঙ্ক এবং অ্যাওয়েট এগুলি না করার জন্য অ্যাসিঙ্ক্রোনাস কল ব্যবহার করা হয় । আপনাকে এটির জন্য টাস্ক লিবারি ব্যবহার করতে হবে , যেমন টাস্ক.রুন ()।

এখানে অপেক্ষা এবং কোনওটির সমাধানের জন্য অপেক্ষা করার মধ্যে একটি তুলনা করা হচ্ছে

এটি কোনওটিই অ্যাসিঙ্ক সমাধান নয়:

    public static long DoTask()
    {
        stopWatch.Reset();
        stopWatch.Start();

        // [RUNS ON MAIN THREAD]
        var task = Task.Run(() => {
            Thread.Sleep(2000);
            // [RUNS ON WORKER THREAD]
        });
        // goes directly further
        // WITHOUT waiting until the task is finished

        // [RUNS ON MAIN THREAD]

        stopWatch.Stop();
        // 50 milliseconds
        return stopWatch.ElapsedMilliseconds;
    }

এটি অ্যাসিঙ্ক পদ্ধতি:

    public async static Task<long> DoAwaitTask()
    {
        stopWatch.Reset();
        stopWatch.Start();

        // [RUNS ON MAIN THREAD]

        await Task.Run(() => {
            Thread.Sleep(2000);
            // [RUNS ON WORKER THREAD]
        });
        // Waits until task is finished

        // [RUNS ON MAIN THREAD]

        stopWatch.Stop();
        // 2050 milliseconds
        return stopWatch.ElapsedMilliseconds;
    }

আপনি অপেক্ষা না করা কীওয়ার্ড ব্যতীত একটি অ্যাসিঙ্ক পদ্ধতিতে কল করতে পারেন তবে এর অর্থ এখানে যে কোনও ব্যতিক্রম প্রকাশের মোডে গ্রাস করা হয়েছে:

    public static Stopwatch stopWatch { get; } = new Stopwatch();

    static void Main(string[] args)
    {
        Console.WriteLine("DoAwaitTask: " + DoAwaitTask().Result + " ms");
        // 2050 (2000 more because of the await)
        Console.WriteLine("DoTask: " + DoTask() + " ms");
        // 50
        Console.ReadKey();
    }

Async এবং Await সমান্তরাল কম্পিউটিং জন্য বোঝানো হয় না। এগুলি আপনার মূল থ্রেডটি ব্লক না করার জন্য ব্যবহৃত হয়। এটি যখন এসপ নেটওয়ার বা উইন্ডোজ অ্যাপ্লিকেশনগুলির বিষয়ে থাকে, তখন কোনও নেটওয়ার্ক কলের কারণে আপনার মূল থ্রেডটি ব্লক করা খারাপ জিনিস। আপনি যদি এটি করেন তবে আপনার অ্যাপ্লিকেশনটি প্রতিক্রিয়াহীন এমনকি ক্রাশও পাবে।

আরও উদাহরণের জন্য এমএস ডক্স পরীক্ষা করে দেখুন।


9

সৎ আমি এখনও মনে করি সবচেয়ে ভাল ব্যাখ্যা ভবিষ্যৎ এবং উইকিপিডিয়া উপর প্রতিশ্রুতি সম্পর্কে এক হবে: http://en.wikipedia.org/wiki/Futures_and_promises

মূল ধারণাটি হ'ল আপনার কাছে থ্রেডের একটি পৃথক পুল রয়েছে যা অ্যাসিঙ্ক্রোনালিভাবে কার্য সম্পাদন করে। এটি ব্যবহার করার সময়। তবে বস্তুটি প্রতিশ্রুতি দেয় যে এটি কোনও সময় অপারেশনটি সম্পাদন করবে এবং আপনি যখন অনুরোধ করবেন তখন আপনাকে ফলাফল দেবে। এর অর্থ হ'ল আপনি ফলাফলটি অনুরোধ করার সময় এবং এটি শেষ না হয়ে অবরুদ্ধ হবে, তবে অন্যথায় থ্রেড পুলে সম্পাদন করুন।

সেখান থেকে আপনি জিনিসগুলি অনুকূল করতে পারেন: কিছু ক্রিয়াকলাপ async বাস্তবায়িত হতে পারে এবং পরবর্তী ফাইলগুলি এবং I / অথবা পুনরায় অর্ডার করে ফাইল আইও এবং নেটওয়ার্ক যোগাযোগের মতো জিনিসগুলি অনুকূল করতে পারেন। আমি নিশ্চিত নই যে এটি ইতিমধ্যে মাইক্রোসফ্টের টাস্ক কাঠামোর মধ্যে রয়েছে কিনা - তবে এটি যদি না হয় তবে আমি যুক্ত হওয়া প্রথম জিনিসগুলির মধ্যে এটি একটি হবে।

আপনি প্রকৃতপক্ষে C # 4.0 এ ফলন সহ ভবিষ্যতের প্যাটার্ন সাজানোর বাস্তবায়ন করতে পারেন। যদি আপনি এটি ঠিক কীভাবে কাজ করে তা জানতে চান, তবে আমি এই লিঙ্কটি একটি ভাল কাজ করে এমনটি প্রস্তাব করতে পারি: http://code.google.com/p/fracture/source/browse/trunk/Squared/TaskLib/ । যাইহোক, আপনি যদি এটির সাথে নিজেই কাজ শুরু করেন তবে আপনি খেয়াল করবেন যে আপনার যদি দুর্দান্ত সমস্ত কাজ করতে চান তবে আপনার ভাষা সমর্থন দরকার - যা মাইক্রোসফ্ট ঠিক তাই করেছিল।


8

টাস্ক, টাস্ক.ওয়েটএল (), অ্যাসিঙ্ক এবং অপেক্ষার ব্যবহারগুলি দেখায় এমন একটি সাধারণ কনসোল অ্যাপ্লিকেশন চালানোর জন্য এই ফ্রিডল https://dotnetfiddle.net/VhZdLU দেখুন (এবং সম্ভব হলে এটি উন্নত করুন ) একই প্রোগ্রামে অপারেটর।

এই ফ্রিডলটি আপনার কার্যকরকরণ চক্র ধারণাটি সাফ করবে।

এখানে নমুনা কোড

using System;
using System.Threading.Tasks;

public class Program
{
    public static void Main()
    {               
        var a = MyMethodAsync(); //Task started for Execution and immediately goes to Line 19 of the code. Cursor will come back as soon as await operator is met       
        Console.WriteLine("Cursor Moved to Next Line Without Waiting for MyMethodAsync() completion");
        Console.WriteLine("Now Waiting for Task to be Finished");       
        Task.WaitAll(a); //Now Waiting      
        Console.WriteLine("Exiting CommandLine");       
    }

    public static async Task MyMethodAsync()
    {
        Task<int> longRunningTask = LongRunningOperation();
        // independent work which doesn't need the result of LongRunningOperationAsync can be done here
        Console.WriteLine("Independent Works of now executes in MyMethodAsync()");
        //and now we call await on the task 
        int result = await longRunningTask;
        //use the result 
        Console.WriteLine("Result of LongRunningOperation() is " + result);
    }

    public static async Task<int> LongRunningOperation() // assume we return an int from this long running operation 
    {
        Console.WriteLine("LongRunningOperation() Started");
        await Task.Delay(2000); // 2 second delay
        Console.WriteLine("LongRunningOperation() Finished after 2 Seconds");
        return 1;
    }   

}

আউটপুট উইন্ডো থেকে ট্রেস আসছে: এখানে চিত্র বর্ণনা লিখুন


3
public static void Main(string[] args)
{
    string result = DownloadContentAsync().Result;
    Console.ReadKey();
}

// You use the async keyword to mark a method for asynchronous operations.
// The "async" modifier simply starts synchronously the current thread. 
// What it does is enable the method to be split into multiple pieces.
// The boundaries of these pieces are marked with the await keyword.
public static async Task<string> DownloadContentAsync()// By convention, the method name ends with "Async
{
    using (HttpClient client = new HttpClient())
    {
        // When you use the await keyword, the compiler generates the code that checks if the asynchronous operation is finished.
        // If it is already finished, the method continues to run synchronously.
        // If not completed, the state machine will connect a continuation method that must be executed WHEN the Task is completed.


        // Http request example. 
        // (In this example I can set the milliseconds after "sleep=")
        String result = await client.GetStringAsync("http://httpstat.us/200?sleep=1000");

        Console.WriteLine(result);

        // After completing the result response, the state machine will continue to synchronously execute the other processes.


        return result;
    }
}

3

উচ্চতর স্তরে:

1) অ্যাসিঙ্ক কীওয়ার্ডটি অপেক্ষা করতে সক্ষম করে এবং এটিই এটি করে। অ্যাসিঙ্ক কীওয়ার্ডটি পৃথক থ্রেডে পদ্ধতিটি চালায় না। একটি সময় সাশ্রয়ী মূল্যের কাজের জন্য অপেক্ষা না করা অবধি শুরুর এফ অ্যাসিঙ্ক পদ্ধতিটি সিঙ্ক্রোনাসে চলে runs

2) আপনি এমন কোনও পদ্ধতির জন্য অপেক্ষা করতে পারেন যা টাস্ক বা টাইপ টি টাইপের ফেরত দেয় আপনি অ্যাসিঙ্ক শূন্য পদ্ধতিতে অপেক্ষা করতে পারবেন না।

3) সময় গ্রহণকারী কার্যের জন্য প্রধান থ্রেডের মুখোমুখি হওয়া মুহূর্তগুলি বা আসল কাজ শুরু হওয়ার পরে, মূল থ্রেড বর্তমান পদ্ধতির কলারে ফিরে আসে।

৪) যদি মূল থ্রেডটি এমন কোনও কাজের জন্য অপেক্ষা করে যা এখনও কার্যকর হয় তবে এটি তার জন্য অপেক্ষা করে না এবং বর্তমান পদ্ধতির কলারে ফিরে আসে। এইভাবে, অ্যাপ্লিকেশনটি প্রতিক্রিয়াশীল থেকে যায়।

5) প্রসেসিং টাস্কের জন্য অপেক্ষা করা, এখন থ্রেড পুল থেকে পৃথক থ্রেডে কার্যকর করা হবে।

)) এই অপেক্ষার কাজটি শেষ হয়ে গেলে, এর নীচের সমস্ত কোড পৃথক থ্রেড দ্বারা কার্যকর করা হবে

নীচে নমুনা কোড দেওয়া আছে। এটি কার্যকর করুন এবং থ্রেড আইডি চেক করুন

using System;
using System.Threading;
using System.Threading.Tasks;

namespace AsyncAwaitDemo
{
    class Program
    {
        public static async void AsynchronousOperation()
        {
            Console.WriteLine("Inside AsynchronousOperation Before AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            //Task<int> _task = AsyncMethod();
            int count = await AsyncMethod();

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod Before Await, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            //int count = await _task;

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await Before DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            DependentMethod(count);

            Console.WriteLine("Inside AsynchronousOperation After AsyncMethod After Await After DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
        }

        public static async Task<int> AsyncMethod()
        {
            Console.WriteLine("Inside AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
            int count = 0;

            await Task.Run(() =>
            {
                Console.WriteLine("Executing a long running task which takes 10 seconds to complete, Thread Id: " + Thread.CurrentThread.ManagedThreadId);
                Thread.Sleep(20000);
                count = 10;
            });

            Console.WriteLine("Completed AsyncMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            return count;
        }       

        public static void DependentMethod(int count)
        {
            Console.WriteLine("Inside DependentMethod, Thread Id: " + Thread.CurrentThread.ManagedThreadId + ". Total count is " + count);
        }

        static void Main(string[] args)
        {
            Console.WriteLine("Started Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            AsynchronousOperation();

            Console.WriteLine("Completed Main method, Thread Id: " + Thread.CurrentThread.ManagedThreadId);

            Console.ReadKey();
        }

    }
}

2

আমি এটা বুঝতে এছাড়াও, একটি তৃতীয় মেয়াদে মিশ্রণ যোগ করা সেখানে উচিত: Task

Async এটি কেবলমাত্র একটি যোগ্যতা যা আপনি আপনার পদ্ধতিতে বলছেন এটি একটি অ্যাসিনক্রোনাস পদ্ধতি।

Taskasyncফাংশন ফিরে । এটি তাত্পর্যপূর্ণভাবে কার্যকর করে।

আপনি awaitএকটি কাজ। কোড এক্সিকিউশন এই লাইনে পৌঁছে গেলে নিয়ন্ত্রণ আপনার চারপাশের মূল ফাংশনটির কলারে ফিরে আসে।

যদি পরিবর্তে, আপনি একটি ফেরত ধার্য asyncফাংশন (যেমন Taskএকটি পরিবর্তনশীল, এর) যখন কোড সঞ্চালনের এই লাইন ছুঁয়েছে, এটা ঠিক চলতে যে লাইন গত পার্শ্ববর্তী ফাংশনে যখনTask , executes অ্যাসিঙ্ক্রোনাস।


1

দীর্ঘ মেয়াদী যুক্তি সম্পাদন করতে তাদের ব্যাকগ্রাউন্ড থ্রেডের সমান ব্যবহার করছেন?

এই নিবন্ধটি এমডিএসএন: অ্যাসিঙ্ক এবং ওয়েট (সি #) সহ অ্যাসিনক্রোনাস প্রোগ্রামিং এটিকে স্পষ্টভাবে ব্যাখ্যা করেছে:

অ্যাসিঙ্ক এবং প্রতীক্ষিত কীওয়ার্ডগুলির কারণে অতিরিক্ত থ্রেড তৈরি হওয়ার কারণ হয় না। অ্যাসিঙ্ক পদ্ধতিতে মাল্টিথ্রেডিংয়ের প্রয়োজন হয় না কারণ একটি অ্যাসিঙ্ক পদ্ধতিটি তার নিজস্ব থ্রেডে চালিত হয় না। পদ্ধতিটি বর্তমান সিঙ্ক্রোনাইজেশন প্রসঙ্গে চলে এবং পদ্ধতিটি সক্রিয় থাকাকালীন থ্রেডে সময় ব্যবহার করে।


1

নিম্নলিখিত কোডে, এইচটিপিপি্লিয়েন্ট পদ্ধতিটি গেটবাইটআরেএসিঙ্ক একটি টাস্ক, getContentsTask প্রদান করে। টাস্কটি সম্পূর্ণ হয়ে গেলে আসল বাইট অ্যারে তৈরি করার প্রতিশ্রুতি। প্রত্যাশিত অপারেটর getContentsTask সম্পূর্ণ না হওয়া পর্যন্ত SumPageSizesAsync এ এক্সিকিউশন স্থগিত করার জন্য getContentsTask এ প্রয়োগ করা হবে। ইতিমধ্যে, নিয়ন্ত্রণটি SumPageS आकारAsync এর কলারে ফিরে আসে। যখন getContentsTask সমাপ্ত হয়, প্রতীক্ষিত এক্সপ্রেশনটি বাইট অ্যারেতে মূল্যায়ন করে।

private async Task SumPageSizesAsync()
{
    // To use the HttpClient type in desktop apps, you must include a using directive and add a 
    // reference for the System.Net.Http namespace.
    HttpClient client = new HttpClient();
    // . . .
    Task<byte[]> getContentsTask = client.GetByteArrayAsync(url);
    byte[] urlContents = await getContentsTask;

    // Equivalently, now that you see how it works, you can write the same thing in a single line.
    //byte[] urlContents = await client.GetByteArrayAsync(url);
    // . . .
}

1

নীচে এমন কোড রয়েছে যা ডায়লগ খোলার মাধ্যমে এক্সেল ফাইলটি পড়ে এবং তারপরে অ্যাসিঙ্ক ব্যবহার করে এবং অ্যাসিঙ্ক্রোনাস কোডটি চালানোর জন্য অপেক্ষা করুন যা এক্সেল থেকে এক লাইনে এক করে পড়ে গ্রিডে বাঁধা

namespace EmailBillingRates
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            lblProcessing.Text = "";
        }

        private async void btnReadExcel_Click(object sender, EventArgs e)
        {
            string filename = OpenFileDialog();

            Microsoft.Office.Interop.Excel.Application xlApp = new Microsoft.Office.Interop.Excel.Application();
            Microsoft.Office.Interop.Excel.Workbook xlWorkbook = xlApp.Workbooks.Open(filename);
            Microsoft.Office.Interop.Excel._Worksheet xlWorksheet = xlWorkbook.Sheets[1];
            Microsoft.Office.Interop.Excel.Range xlRange = xlWorksheet.UsedRange;
            try
            {
                Task<int> longRunningTask = BindGrid(xlRange);
                int result = await longRunningTask;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message.ToString());
            }
            finally
            {
                //cleanup  
               // GC.Collect();
                //GC.WaitForPendingFinalizers();

                //rule of thumb for releasing com objects:  
                //  never use two dots, all COM objects must be referenced and released individually  
                //  ex: [somthing].[something].[something] is bad  

                //release com objects to fully kill excel process from running in the background  
                Marshal.ReleaseComObject(xlRange);
                Marshal.ReleaseComObject(xlWorksheet);

                //close and release  
                xlWorkbook.Close();
                Marshal.ReleaseComObject(xlWorkbook);

                //quit and release  
                xlApp.Quit();
                Marshal.ReleaseComObject(xlApp);
            }

        }

        private void btnSendEmail_Click(object sender, EventArgs e)
        {

        }

        private string OpenFileDialog()
        {
            string filename = "";
            OpenFileDialog fdlg = new OpenFileDialog();
            fdlg.Title = "Excel File Dialog";
            fdlg.InitialDirectory = @"c:\";
            fdlg.Filter = "All files (*.*)|*.*|All files (*.*)|*.*";
            fdlg.FilterIndex = 2;
            fdlg.RestoreDirectory = true;
            if (fdlg.ShowDialog() == DialogResult.OK)
            {
                filename = fdlg.FileName;
            }
            return filename;
        }

        private async Task<int> BindGrid(Microsoft.Office.Interop.Excel.Range xlRange)
        {
            lblProcessing.Text = "Processing File.. Please wait";
            int rowCount = xlRange.Rows.Count;
            int colCount = xlRange.Columns.Count;

            // dt.Column = colCount;  
            dataGridView1.ColumnCount = colCount;
            dataGridView1.RowCount = rowCount;

            for (int i = 1; i <= rowCount; i++)
            {
                for (int j = 1; j <= colCount; j++)
                {
                    //write the value to the Grid  
                    if (xlRange.Cells[i, j] != null && xlRange.Cells[i, j].Value2 != null)
                    {
                         await Task.Delay(1);
                         dataGridView1.Rows[i - 1].Cells[j - 1].Value =  xlRange.Cells[i, j].Value2.ToString();
                    }

                }
            }
            lblProcessing.Text = "";
            return 0;
        }
    }

    internal class async
    {
    }
}

0

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

"অপেক্ষা" শব্দটি আক্ষরিক, সুতরাং আপনি যে থ্রেড এ কল করবেন তা চালিয়ে যাওয়ার আগে পদ্ধতির ফলাফলের জন্য অপেক্ষা করবে। উপর ফোরগ্রাউন্ড থ্রেড, এই একটি হল দুর্যোগ । অগ্রভাগ থ্রেড আপনার অ্যাপ্লিকেশন তৈরির বোঝা বহন করে, ভিউ, ভিউ মডেল, প্রাথমিক অ্যানিমেশন এবং এই উপাদানগুলির সাথে আপনার বুট-স্ট্রেপযুক্ত যা কিছু রয়েছে including সুতরাং আপনি যখন অগ্রভাগের থ্রেডের জন্য অপেক্ষা করেন, আপনি অ্যাপটি বন্ধ করে দিন। যখন কিছু ঘটে না দেখা যায় তখন ব্যবহারকারী অপেক্ষা করে অপেক্ষা করে। এটি একটি নেতিবাচক ব্যবহারকারীর অভিজ্ঞতা সরবরাহ করে।

আপনি অবশ্যই বিভিন্ন উপায় ব্যবহার করে অবশ্যই ব্যাকগ্রাউন্ড থ্রেডের জন্য অপেক্ষা করতে পারেন:

Device.BeginInvokeOnMainThread(async () => { await AnyAwaitableMethod(); });

// Notice that we do not await the following call, 
// as that would tie it to the foreground thread.
try
{
Task.Run(async () => { await AnyAwaitableMethod(); });
}
catch
{}

এই মন্তব্যগুলির জন্য সম্পূর্ণ কোডটি এখানে রয়েছে https://github.com/marcusts/xamarin-forms-annoyance এ রয়েছে । AwaitAsyncAntipattern.sln নামক সমাধানটি দেখুন।

গিটহাব সাইটটি এই বিষয়ে আরও বিস্তারিত আলোচনার লিঙ্ক সরবরাহ করে।


1
আমি যা বুঝতে পারি তা থেকে async / awaitকলব্যাকগুলির জন্য সিনট্যাকটিক চিনি, থ্রেডিংয়ের সাথে এর কোনও যোগসূত্র নেই। msdn.microsoft.com/en-us/magazine/hh456401.aspx এটি নন-সিপিইউ বাউন্ড কোডের জন্য, যেমন ইনপুট বা বিলম্বের অপেক্ষায়। Task.Runকেবল সিপিইউ-বাউন্ড কোড ব্লগের
জ্যামিতিকাল

The term "await" is literal, so whatever thread you call it on will wait for the result of the method before continuing.এটি সত্য নয় - সম্ভবত আপনি টাস্ক.ওয়েট () বোঝাতে চেয়েছিলেন? আপনি যখন ব্যবহার করবেন তখন awaitএটি বাকি পদ্ধতিটি নির্বাহের জন্য একটি ধারাবাহিকতা হিসাবে সেট করে যখন আপনি যা-ইডিট অপেক্ষা করেন তা সম্পূর্ণ হয়। এটি আপনি যে পদ্ধতিতে ব্যবহার করেছেন সেটিকে ছাড়ায়, তাই কলার চালিয়ে যেতে পারে can তারপরে যখন প্রতীক্ষা-এড লাইনটি সম্পূর্ণ হয়ে যায় তখন এটি কিছু থ্রেডে (সাধারণত একটি কর্মী থ্রেড) সেই পদ্ধতিটির বাকি অংশ শেষ করে।
ডন চ্যাডল

@ জিওমেট্রিকাল একেবারে মূল, নেট থ্রেডস মুক্ত করারasync/await বিষয়ে about আপনি যখন সত্যই একটি অ্যাসিঙ্ক অপারেশন (যেমন। নেট এর ফাইল.উরাইটএ্যাসেন্স) করেন, এটি আপনার ব্যবহৃত পদ্ধতির বাকী অংশটি স্থগিত করে , তাই কলার চালিয়ে যেতে এবং সম্ভাব্যতার সাথে তার উদ্দেশ্যটি শেষ করতে পারে। থেড অপারেশনের জন্য কোনও থ্রেড অবরুদ্ধ বা অপেক্ষা করছে না । আপনার সম্পাদনা করা অপারেশনটি সম্পূর্ণ হয়ে গেলে, পদ্ধতির বাকী অংশটি একটি থ্রেডে রেখে কার্যকর করা হয় (কল-ব্যাক আইডিয়াটির মতো)। awaitawaitawaitawaitasync/await
ডন চ্যাডল
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.