টাস্ক <কী> কীভাবে একটি ইনট হয়ে যায়?


116

আমাদের এই পদ্ধতিটি রয়েছে:

async Task<int> AccessTheWebAsync()
{ 
    HttpClient client = new HttpClient();

   Task<string> getStringTask = client.GetStringAsync("http://msdn.microsoft.com");

   // You can do work here that doesn't rely on the string from GetStringAsync.
   DoIndependentWork();

   string urlContents = await getStringTask;
   //The thing is that this returns an int to a method that has a return type of Task<int>
   return urlContents.Length;
}

একটি অন্তর্নিহিত রূপান্তর মধ্যে ঘটবে না Task<int>এবং int? তা না হলে কি হচ্ছে? কীভাবে এটি কার্যকর হয়?


1
পড়তে থাকুন । আমি ধরে নিয়েছি সংকলক asyncকীওয়ার্ডের উপর ভিত্তি করে সেটির যত্ন নেয় ।
ডি স্ট্যানলে

1
@Freeman, এই মহান ব্যাখ্যা তাকান: stackoverflow.com/a/4047607/280758
qehgt

উত্তর:


171

টাস্ক <> এবং ইনট এর মধ্যে কি অন্তর্নিহিত রূপান্তর ঘটে?

নাঃ। এটি কীভাবে async/ awaitকাজ করে তার একটি অংশ ।

হিসাবে ঘোষিত যে কোনও পদ্ধতিতে এর asyncরিটার্ন টাইপ থাকতে হবে:

  • void (সম্ভব হলে এড়ানো)
  • Task (সমাপ্তি / ব্যর্থতার বিজ্ঞপ্তির বাইরে কোনও ফল নেই)
  • Task<T>( Tএকটি অ্যাসিঙ্ক পদ্ধতিতে টাইপের যৌক্তিক ফলাফলের জন্য )

সংকলক সমস্ত উপযুক্ত মোড়ক করে। মুল বক্তব্যটি হ'ল আপনি অবিচ্ছিন্নভাবে ফিরে যাচ্ছেন urlContents.Length- আপনি পদ্ধতিটি কেবল ফিরে আসতে পারবেন না int, কারণ এটি awaitইতিমধ্যে সম্পূর্ণ না হওয়া প্রথম এক্সপ্রেশনকে আঘাত করলে আসল পদ্ধতিটি ফিরে আসবে । সুতরাং পরিবর্তে, এটি একটি ফিরে আসে Task<int>যা অ্যাসিঙ্ক পদ্ধতিটি নিজেই সম্পূর্ণ হয়ে যায় complete

লক্ষ্য করুন awaitতার বিপরীত কাজ করে - এটা unwraps একটি Task<T>একটি থেকে Tমান, কীভাবে এই লাইন কাজ করে:

string urlContents = await getStringTask;

... তবে অবশ্যই এটি অবিচ্ছিন্নভাবে আবদ্ধ হয়, যেখানে Resultটাস্ক শেষ না হওয়া অবধি কেবল ব্যবহার বন্ধ হয়ে যাবে। ( awaitঅপেক্ষাকৃত নিদর্শন প্রয়োগ করে এমন অন্যান্য ধরণের মোড়ক উন্মোচন করতে পারে তবে Task<T>আপনি সম্ভবত এটি ব্যবহার করতে পারেন))

এই দ্বৈত মোড়ক / আন-র্যাপিং হ'ল যা অ্যাসিঙ্ককে এত কমপোজযোগ্য হতে দেয়। উদাহরণস্বরূপ, আমি আর একটি অ্যাসিঙ্ক পদ্ধতি লিখতে পারলাম যা আপনাকে কল করে এবং ফলাফলটি দ্বিগুণ করে:

public async Task<int> AccessTheWebAndDoubleAsync()
{
    var task = AccessTheWebAsync();
    int result = await task;
    return result * 2;
}

(বা সহজভাবে return await AccessTheWebAsync() * 2;অবশ্যই।)


3
এটি হুডের নীচে কীভাবে কাজ করে তার জন্য কোনও বিবরণ দেওয়া যেতে পারে, কেবল কৌতূহলী।
ফ্রিম্যান

8
+1 সর্বদা হিসাবে ভাল উত্তর। এবং কেন আপনি এত সুন্দর এগুলি লিখছেন ?!
ফেলিক্স কে।

9
+1: সবেমাত্র সন্ধান করা শুরু করেছে async/ awaitএবং আমি এটি চূড়ান্ত অ-স্বজ্ঞাত বলে মনে করি। আইএমও, returnএটি পরিষ্কার করার জন্য এখানে একটি কীওয়ার্ড বা অনুরূপ হওয়া উচিত , উদাহরণস্বরূপ return async result;(যেভাবে await result"এর Tথেকে " মুছে ফেলা হয় " Tast<T>)।
ডেভ_আই

2
@JonSkeet কিন্তু এটা ছাড়া অর্থে দেখা যায় না await- সঙ্গে T foo = someTaskT;আপনি পেতে চাই "পরোক্ষভাবে টাইপ রূপান্তর করা যায় না Task<T>করার T" - একই ভাবে আমি তর্ক এটি আরো জানার জন্য হবে বিপরীত (ইন মোড়ানো জন্য একটি শব্দ আছে মধ্যে Task<T>)। আমি সবই ফ্লফ অপসারণের জন্য রয়েছি তবে এই ক্ষেত্রে আমি মনে করি এটি asyncপদ্ধতিগুলির মধ্যে একটি অপ্রয়োজনীয় অবহেলা সরবরাহ করে। (স্পষ্টতই
বক্তব্যটি

2
@ ডেভ_আই: অ্যাসাইনমেন্টটি কোনও অর্থবোধ করে না, তবে বাকিগুলি তা করে। এবং এমন কিছু ক্ষেত্রে রয়েছে যেখানে পুরো বিবৃতিটি বোঝায় - যদিও এটি কার্যকর নাও হতে পারে। পদ্ধতিটি ইতিমধ্যে ঘোষিত হয়ে গেছে বলে asyncআমি মনে করি এটি যথেষ্ট।
জন স্কিটি

18

টাস্ককে ইন্টিতে রূপান্তর করার দরকার নেই। সহজভাবে কার্য ফলাফলটি ব্যবহার করুন।

int taskResult = AccessTheWebAndDouble().Result;

public async Task<int> AccessTheWebAndDouble()
{
    int task = AccessTheWeb();
    return task;
}

এটি যদি পাওয়া যায় তবে মানটি ফিরিয়ে দেবে অন্যথায় এটি 0 ফেরত দেয়।


20
এটা আমি জিজ্ঞাসা কি নয়।
ফ্রিম্যান

16
এটি প্রশ্নের উত্তর দেয় না। তবে আরও গুরুত্বপূর্ণ বিষয় এটি খুব খারাপ পরামর্শ । আপনার প্রায় কখনও ব্যবহার করা উচিত নয়Result ; এটা অচলাবস্থা হতে পারে! উদাহরণস্বরূপ এই কর্মপ্রবাহটি বিবেচনা করুন: (1) একটি নোট লিখুন যা "লনকে কাঁচা" বলবে। (২) লনটি কাঁচা কাটার জন্য অপেক্ষা করুন (৩) একটি স্যান্ডউইচ খান, (৪) নোটে যা কিছু বলা আছে তা করুন "work এই কর্মপ্রবাহের সাহায্যে আপনি কখনও স্যান্ডউইচ খাবেন না বা লন কাঁচা কাটাবেন না, কারণ ২ য় পদক্ষেপ একটি সংলগ্ন অপেক্ষা ভবিষ্যতে আপনি যা করবেন এমন কিছু নিয়ে । তবে আপনি এখানে বর্ণনা করছেন এমন ওয়ার্কফ্লো।
এরিক লিপার্ট

@ এরিকলিপার্ট: আপনার উদাহরণ পরিষ্কার করবেন না। আপনি কী দয়া করে ব্যাখ্যা করতে পারবেন যে অপেক্ষার অবসান না হলে ফলাফল কীভাবে ডেডলকগুলি প্রবর্তন করতে পারে?
চরিতজে

3
অপেক্ষার অর্থ ফলাফলের অপেক্ষায় থাকাকালীন কিছু করা এবং ফলাফলটি গণনার জন্য কোনও কাজ অন্তর্ভুক্ত থাকতে পারে। তবে সিঙ্ক্রোনাস ওয়েটস আপনি অপেক্ষা করতে করতে কিছুই করেন না যার অর্থ আপনি কাজটি শেষ হতে আটকাতে পারবেন।
এরিক লিপার্ট

1
@EricLippert। এই একই সমস্যা হবে? 'Task.Run (() => AccessTheWebAndDouble ())। ফলাফল;'
CharithJ
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.