সতর্কতা এই কলটি প্রতীক্ষিত নয়, বর্তমান পদ্ধতির বাস্তবায়ন অব্যাহত রয়েছে


135

সবে VS2012 পেয়েছে এবং একটি হ্যান্ডেল চালু করার চেষ্টা করছে async

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

// contrived example (edited in response to Servy's comment)
public static Task<string> PromptForStringAsync(string prompt)
{
    return Task.Factory.StartNew(() => {
        Console.Write(prompt);
        return Console.ReadLine();
    });
}

এখানে এটির একটি উদাহরণ পদ্ধতি রয়েছে। যদি PromptForStringAsyncঅ্যাসিঙ্ক না হয় তবে এই পদ্ধতির জন্য কলব্যাকের মধ্যে কলব্যাকের নীড়ের প্রয়োজন require অ্যাসিঙ্কের সাথে আমি আমার পদ্ধতিটি খুব প্রাকৃতিক উপায়ে লিখতে চাই:

public static async Task GetNameAsync()
{
    string firstname = await PromptForStringAsync("Enter your first name: ");
    Console.WriteLine("Welcome {0}.", firstname);

    string lastname = await PromptForStringAsync("Enter your last name: ");
    Console.WriteLine("Name saved as '{0} {1}'.", firstname, lastname);
}

এ পর্যন্ত সব ঠিকই. আমি যখন getNameAsync কল করি তখন সমস্যাটি হয় :

public static void DoStuff()
{
    GetNameAsync();
    MainWorkOfApplicationIDontWantBlocked();
}

পুরো বিষয়টি GetNameAsyncহ'ল এটি অ্যাসিনক্রোনাস। আমি এটিকে ব্লক করতে চাই না , কারণ আমি মেইনওয়ার্কঅফ অ্যাপ্লিকেশন আইডোনটওয়ান্ট ব্লক করা ASAP এ ফিরে যেতে চাই এবং getNameAsyncটিকে ব্যাকগ্রাউন্ডে এটি করতে দিন। যাইহোক, এটিকে এভাবে কল করা আমাকে GetNameAsyncলাইনে একটি সংকলক সতর্কতা দেয় :

Warning 1   Because this call is not awaited, execution of the current method continues before the call is completed. Consider applying the 'await' operator to the result of the call.

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

আমি আমার কোডটি সতর্কতা ছাড়াই সংকলন করতে পছন্দ করি, তবে এখানে "ফিক্স" করার কিছুই নেই কারণ কোডটি আমি যা করতে চাইছি ঠিক তাই করছে। এর রিটার্ন মান সংরক্ষণ করে আমি সতর্কতা থেকে মুক্তি পেতে পারি GetNameAsync:

public static void DoStuff()
{
    var result = GetNameAsync(); // supress warning
    MainWorkOfApplicationIDontWantBlocked();
}

তবে এখন আমার অতিরিক্ত ব্যবহার্য কোড রয়েছে। ভিজ্যুয়াল স্টুডিওতে বোঝা যাচ্ছে যে আমি এই অপ্রয়োজনীয় কোডটি লিখতে বাধ্য হয়েছিল, কারণ এটি স্বাভাবিক "কখনই ব্যবহৃত হয় না" সতর্কতা দমন করে।

অ্যাসিঙ্ক নয় এমন কোনও পদ্ধতিতে GetNameAsync মোড়ানো দ্বারাও আমি সতর্কতা থেকে মুক্তি পেতে পারি:

    public static Task GetNameWrapper()
    {
        return GetNameAsync();
    }

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

আমার অসম্পূর্ণ ব্যবহার সম্পর্কে এখানে কি ভুল আছে?


2
বিটিডব্লিউ, বাস্তবায়ন PromptForStringAsyncকরার সময় আপনার প্রয়োজনের চেয়ে বেশি কাজ করুন; শুধু ফলাফল ফিরে Task.Factory.StartNew। এটি ইতিমধ্যে একটি কাজ যাঁর মান কনসোলে প্রবেশ করা স্ট্রিং। ফলাফলটির প্রত্যাবর্তনের অপেক্ষা করার দরকার নেই; এটি করার ফলে কোনও নতুন মান যুক্ত হয় না।
পরিবেশন করুন

Wwouldn't এটি আরো জানার জন্য জন্য GetNameAsyncপুরো নাম ঐ ব্যবহারকারীর সরবরাহ করা হয়েছিল (অর্থাত প্রদান Task<Name>, বরং শুধু একটি ফেরার চেয়ে Task? DoStuffএবং হয় তারপর যে কাজটি সংরক্ষণ করতে পারে, awaitএটা পরে অন্যান্য পদ্ধতি, অথবা এমনকি কাজের যে অন্যান্য পাস পদ্ধতি, যাতে এটি করতে পারে awaitবা Waitএটা কোথাও এটা বাস্তবায়ন ভেতরে।
Servy

@ সার্ভি: আমি যদি কেবল এই টাস্কটি ফিরিয়ে দিই তবে আমি একটি ত্রুটি পেয়েছি "যেহেতু এটি একটি অ্যাসিঙ্ক পদ্ধতি, সুতরাং প্রত্যাবর্তনের এক্সপ্রেশনটি অবশ্যই 'টাস্ক <স্ট্রিং>' এর পরিবর্তে 'স্ট্রিং' টাইপের হতে হবে।
মাটি

1
asyncকীওয়ার্ডটি সরান ।
পরিবেশন করুন

13
আইএমও, সি # টিমের পক্ষ থেকে সতর্কতার জন্য এটি একটি দুর্বল পছন্দ ছিল। সতর্কতাগুলি অবশ্যই সেই জিনিসগুলির জন্য হওয়া উচিত যা প্রায় অবশ্যই ভুল। এমন অনেকগুলি কেস রয়েছে যেখানে আপনি একটি অ্যাসিঙ্ক পদ্ধতি "ফায়ার-এন্ড-ভুলে" যেতে চান এবং অন্য সময়ে যেখানে আপনি আসলে এটির জন্য অপেক্ষা করতে চান।
MgSam

উত্তর:


103

যদি আপনার সত্যিকারের ফলাফলের প্রয়োজন না হয় তবে GetNameAsyncআপনি ফিরে আসার জন্য কেবল স্বাক্ষরটি পরিবর্তন করতে পারেন void:

public static async void GetNameAsync()
{
    ...
}

সম্পর্কিত প্রশ্নের উত্তর দেখতে বিবেচনা করুন: শূন্যতা ফিরে দেওয়া এবং কোনও কার্য ফেরানোর মধ্যে পার্থক্য কী?

হালনাগাদ

যদি আপনার ফলাফলের প্রয়োজন হয়, আপনি GetNameAsyncফিরে আসতে পরিবর্তন করতে পারেন, বলুন Task<string>:

public static async Task<string> GetNameAsync()
{
    string firstname = await PromptForStringAsync("Enter your first name: ");
    string lastname = await PromptForStringAsync("Enter your last name: ");
    return firstname + lastname;
}

এবং এটি নিম্নলিখিত হিসাবে ব্যবহার করুন:

public static void DoStuff()
{
    Task<string> task = GetNameAsync();

    // Set up a continuation BEFORE MainWorkOfApplicationIDontWantBlocked
    Task anotherTask = task.ContinueWith(r => {
            Console.WriteLine(r.Result);
        });

    MainWorkOfApplicationIDontWantBlocked();

    // OR wait for the result AFTER
    string result = task.Result;
}

15
যে শুধুমাত্র ক্ষেত্রে হবে যদি সে কখনো শুধু ফলাফলের প্রয়োজন না উল্টোদিকে ফলাফলের বজায় রাখে, এই এক সময়
পরিবেশন করুন

3
@ সার্ভে, ঠিক আছে, স্পষ্টতার জন্য ধন্যবাদ। তবে ওপি'র GetNameAsyncকোনও মানই আসে না (ফলাফলটি নিজেই বাদে অবশ্যই)।
নিকোলে খিল

2
সঠিক, তবে কোনও কার্য ফিরে দিয়ে তিনি জানতে পারবেন কখন এটি অ্যাসিঙ্কের সমস্ত ক্রিয়াকলাপ শেষ করে। যদি এটি ফিরে আসে void, কখন হয়ে গেছে তার জানার উপায় নেই। আমি যখন আমার আগের মন্তব্যে "ফলাফল" বলছিলাম তখন এটাই বোঝাচ্ছিল।
সার্ভ করুন

29
একটি সাধারণ নিয়ম হিসাবে, async voidইভেন্ট হ্যান্ডলারের ব্যতীত আপনার কখনও কোনও পদ্ধতি থাকা উচিত নয় ।
ড্যানিয়েল মান

2
এখানে অন্য একটি বিষয় লক্ষণীয় হ'ল আচরণটি অন্যরকম যখন অপ্রকাশিত ব্যতিক্রমগুলির কথা আসে তখন আপনি async voidযে কোনও ব্যতিক্রম স্যুইচ করেন না যা আপনার প্রক্রিয়াটি ক্র্যাশ করবে, কিন্তু .NET 4.5 এ এটি চলতে থাকবে।
কালেব ভের

62

আমি এই আলোচনায় বেশ দেরি করেছি, তবে #pragmaপ্রাক-প্রসেসরের নির্দেশিকা ব্যবহারের বিকল্পও রয়েছে । আমার এখানে কিছু অ্যাসিঙ্ক কোড রয়েছে এবং আমি স্পষ্টভাবে কিছু শর্তে অপেক্ষা করতে চাই না এবং আমি আপনার বাকীগুলির মতো সতর্কতা এবং অব্যবহৃত ভেরিয়েবলগুলি অপছন্দ করি:

#pragma warning disable 4014
SomeMethodAsync();
#pragma warning restore 4014

"4014"এই দুটিই MSDN পাতা থেকে আসে: কম্পাইলার সতর্কতা (স্তর 1) CS4014

@ রায়ান-হোরাথ দ্বারা সতর্কতা / উত্তরটি এখানে দেখুন https://stackoverflow.com/a/12145047/928483

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

সি # 7.0 এর জন্য আপডেট

সি # 7.0 একটি নতুন বৈশিষ্ট্য যুক্ত করেছে, ভেরিয়েবলগুলি বাতিল করে দেয়: ছাড় - সি # গাইড , যা এই ক্ষেত্রে সহায়তা করতে পারে।

_ = SomeMethodAsync();

5
এটি একেবারে দুর্দান্ত। আপনি এই কাজটি করতে পারবেন আমার ধারণা ছিল না। ধন্যবাদ!
ম্যাক্সিম গার্সকোভিচ

1
এটি এমনকি বলতে প্রয়োজন হয় না var, শুধু লেখার_ = SomeMethodAsync();
সত্যজিৎ

41

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

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

সম্প্রসারণ পদ্ধতি:

public static class TaskExtensions
{
    public static void DoNotAwait(this Task task) { }
}

ব্যবহার:

public static void DoStuff()
{
    GetNameAsync().DoNotAwait();
    MainWorkOfApplicationIDontWantBlocked();
}

যোগ করার জন্য সম্পাদিত: এটি জোনাথন অ্যালেনের সমাধানের মতো যেখানে ইতিমধ্যে শুরু না হলে এক্সটেনশন পদ্ধতিটি কাজটি শুরু করবে, তবে আমি একক-উদ্দেশ্যমূলক কাজগুলি করতে পছন্দ করি যাতে কলারের উদ্দেশ্য সম্পূর্ণ পরিষ্কার থাকে clear


1
আমি এটি পছন্দ করি তবে আমি এটির নাম আনওয়াইট ();)
রেখেছি

29

async void খারাপ!

  1. অকার্যকর ফিরে আসা এবং একটি টাস্ক ফিরিয়ে দেওয়ার মধ্যে পার্থক্য কী?
  2. https://jaylee.org/archive/2012/07/08/c-sharp-async-tips-and-tricks-part-2-async-void.html

আমার পরামর্শটি হ'ল আপনি বেনাম Taskপদ্ধতিতে স্পষ্টভাবে চালাবেন ...

যেমন

public static void DoStuff()
{
    Task.Run(async () => GetNameAsync());
    MainWorkOfApplicationIDontWantBlocked();
}

অথবা আপনি যদি এটি আটকাতে চান তবে আপনি বেনামে পদ্ধতিতে অপেক্ষা করতে পারেন

public static void DoStuff()
{
    Task.Run(async () => await GetNameAsync());
    MainWorkOfApplicationThatWillBeBlocked();
}

তবে, যদি আপনার GetNameAsyncপদ্ধতির সাথে ইউআই বা এমনকি যে কোনও কিছু ইউআই-এর সাথে ইন্টারঅ্যাক্ট করতে হয়, (ডাব্লুআইএনআরটি / এমভিভিএম, আমি আপনাকে দেখছি), তবে এটি একটু ফানকিয়ার হয়ে যায় =)

আপনাকে এই জাতীয় UI প্রেরণের রেফারেন্সটি পাস করতে হবে ...

Task.Run(async () => await GetNameAsync(CoreApplication.MainView.CoreWindow.Dispatcher));

এবং তারপরে আপনার অ্যাসিঙ্ক পদ্ধতিতে আপনাকে আপনার ইউআই বা ইউআই বাউন্ড উপাদানগুলির সাথে যোগাযোগ করতে হবে যা ভেবেছিল যে ...

dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {  this.UserName = userName; });

আপনার কার্য এক্সটেনশান দুর্দান্ত। আমি কেন আগে কোনও প্রয়োগ করিনি জানি না।
মিকেল দেই বলিণ্ডার

8
আপনি যে প্রথম পদ্ধতির উল্লেখ করেছেন সেটি একটি পৃথক সতর্কতা সৃষ্টি করে: This async method lacks 'await' operators and will run synchronously. Consider using the 'await' operator to await non-blocking API calls, or 'await Task.Run(...)' to do CPU-bound work on a background thread. এটি একটি নতুন থ্রেড তৈরির কারণও বটে, তবে অ্যাসিঙ্ক / একা অপেক্ষা করার সাথে একটি নতুন থ্রেড অগত্যা তৈরি করা হবে না।
গ্রেগসডেনিস

আপনার উচিৎ স্যার!
ওজকান

16

আমি বর্তমানে এটি করছি:

SomeAyncFunction().RunConcurrently();

যেখানে RunConcurrentlyসংজ্ঞায়িত করা হয়েছে ...

 /// <summary> 
 /// Runs the Task in a concurrent thread without waiting for it to complete. This will start the task if it is not already running. 
 /// </summary> 
 /// <param name="task">The task to run.</param> 
 /// <remarks>This is usually used to avoid warning messages about not waiting for the task to complete.</remarks> 
 public static void RunConcurrently(this Task task) 
 { 
     if (task == null) 
         throw new ArgumentNullException("task", "task is null."); 

     if (task.Status == TaskStatus.Created) 
         task.Start(); 
 } 

https://github.com/docevaad/Anchor/blob/master/Tortuga.Anchor/Tortuga.Anchor.source/shared/TaskUtilities.cs

https://www.nuget.org/packages/Tortuga.Anchor/


1
+1 টি। দেখে মনে হচ্ছে এটি অন্যান্য উত্তরের মন্তব্যে তুলনা করা সমস্ত সমস্যা এড়িয়ে চলে। ধন্যবাদ।
গ্রেট

3
আপনি শুধুমাত্র এই প্রয়োজন: public static void Forget(this Task task) { }
শীতল শাহ

1
আপনি কী বলতে চাইছেন @ শীতলশাহ
জে উইক

@ শীতলশাহ যা কেবলমাত্র অটো-শুরুর কাজগুলির সাথে কাজ করবে যেমনটি তৈরি করা হয়েছে async Task। কিছু কাজ ম্যানুয়ালি শুরু করা দরকার।
জোনাথন অ্যালেন

7

এই সতর্কতা সম্পর্কিত মাইক্রোসফ্ট নিবন্ধ অনুসারে, আপনি কেবল পরিবর্তনশীলকে ফেরত টাস্ক নির্ধারণ করে সমাধান করতে পারেন। নীচে মাইক্রোসফ্ট উদাহরণে প্রদত্ত কোডটির অনুবাদ দেওয়া আছে:

    // To suppress the warning without awaiting, you can assign the 
    // returned task to a variable. The assignment doesn't change how
    // the program runs. However, the recommended practice is always to
    // await a call to an async method.
    // Replace Call #1 with the following line.
    Task delayTask = CalledMethodAsync(delay);

মনে রাখবেন যে এটি করার ফলে পুনঃশার্পারে "স্থানীয় পরিবর্তনশীল কখনও ব্যবহৃত হয় না" বার্তাটি আসবে message


হ্যাঁ, এটি সতর্কবাণীকে দমন করে, কিন্তু না, এটি আসলে কোনও সমস্যার সমাধান করে না। Task-রফার্নিং ফাংশনগুলি বড করা উচিত awaitযদি না আপনি খুব ভাল কারণ না পেয়ে থাকেন। কোনও async voidপদ্ধতি ব্যবহারের ইতিমধ্যে গৃহীত উত্তরের চেয়ে কেন কাজটি বাতিল করা ভাল হবে তা এখানে কোনও কারণ নেই ।

আমি অকার্যকর পদ্ধতিও পছন্দ করি। এটি মাইক্রোসফ্টের চেয়ে স্ট্যাকওভারফ্লোকে আরও স্মার্ট করে তোলে তবে অবশ্যই এটি দেওয়া উচিত।
devlord

4
async voidত্রুটি পরিচালনার চারপাশে গুরুতর সমস্যা এবং অন-টেস্টেবল কোডে ফলাফলের ( আমার এমএসডিএন নিবন্ধটি দেখুন ) পরিচিত করে। ভেরিয়েবলটি ব্যবহার করা আরও ভাল হবে - আপনি যদি নিশ্চিত হন যে আপনি ব্যতিক্রমগুলি নিঃশব্দে গিলতে চান তবে। আরও সম্ভবত, অপটি দুইটি শুরু করতে Taskএবং তারপরে একটি করতে চাইবে await Task.WhenAll
স্টিফেন ক্লিয়ারি

@ স্টেফেনক্লিয়ারি অরক্ষিত কাজগুলি থেকে ব্যতিক্রম উপেক্ষা করা হবে কিনা তা কনফিগারযোগ্য। আপনার কোডটি অন্য কারও প্রকল্পে ব্যবহার করার কোনও সম্ভাবনা থাকলে, তা হতে দেবেন না। আপনার বর্ণনার যে পদ্ধতিগুলির async void DoNotWait(Task t) { await t; }ত্রুটি রয়েছে তা এড়াতে একটি সাধারণ সহায়ক পদ্ধতি ব্যবহার করা যেতে পারে async void। (এবং আমি মনে করি না যে Task.WhenAllওপি কী চায়, তবে এটি খুব ভালভাবে হতে পারে))

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

3

এখানে, একটি সহজ সমাধান।

public static class TasksExtensions
{
    public static void RunAndForget(this Task task)
    {
    }
}

শুভেচ্ছা সহ


1

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

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


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

@ মুড: মাত্র প্রথম এসিঙ্ক কল থেকে দ্বিতীয় কলটিতে প্যারামিটার হিসাবে ফলাফল পাঠান। এইভাবে দ্বিতীয় পদ্ধতিতে কোডটি এখনই শুরু হয় এবং এটির মতো মনে হলে এটি প্রথম কল থেকেই ফলাফলের জন্য অপেক্ষা করতে পারে।
গুফা

আমি এটি করতে পারি, তবে অ্যাসিঙ্ক ছাড়াই এর অর্থ নেস্টেড কলব্যাকস, এর মতো: MethodWithCallback((result1) => { Use(result1); MethodWithCallback((result2) => { Use(result1,result2); })এমনকি এই তুচ্ছ উদাহরণে, এটি পার্স করার পক্ষে একটি দুশ্চরিত্রা। অ্যাসিঙ্কের সাথে, সমান কোডটি আমার জন্য উত্পন্ন হয় যখন আমি লিখি result1 = await AsyncMethod(); Use(result1); result2 = await AsyncMethod(); Use(result1,result2); যা পড়ার পক্ষে অনেক সহজ (যদিও এই মন্তব্যে খুব পঠনযোগ্য উভয়ই একসাথে ছিন্ন করা যায় না!)
মুড

@ মুড: হ্যাঁ তবে আপনি প্রথমের পরে দ্বিতীয় অ্যাসিঙ্ক পদ্ধতিতে কল করতে পারেন, এটির জন্য সিঙ্ক্রোনাস কলটির জন্য অপেক্ষা করার কোনও কারণ নেই Use
গুফা

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


0

আপনি যদি voidফেরার জন্য পদ্ধতিটির স্বাক্ষরটি পরিবর্তন করতে না চান (যেমন ফিরতে voidসর্বদা শূন্য এড হওয়া উচিত ), আপনি C # 7.0+ এই জাতীয় বৈশিষ্ট্যটি বাতিল করুন যা কোনও ভেরিয়েবলকে নির্ধারণের চেয়ে কিছুটা ভাল (এবং বেশিরভাগ ক্ষেত্রে অপসারণ করা উচিত) উত্স বৈধতা সরঞ্জাম সতর্কতা):

public static void DoStuff()
{
    _ = GetNameAsync(); // we don't need the return value (suppresses warning)
    MainWorkOfApplicationIDontWantBlocked();
}
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.