আপনি কীভাবে একটি অ্যাসিঙ্ক অ্যাকশন প্রতিনিধি পদ্ধতি কার্যকর করবেন?


132

একটি সামান্য ব্যাকগ্রাউন্ড তথ্য।

আমি ওয়েব এপিআই স্ট্যাক শিখছি এবং আমি সাফল্য এবং ত্রুটি কোডের মতো পরামিতিগুলির সাথে "ফলাফল" অবজেক্টের আকারে সমস্ত ডেটা এমপ্যাপুলেট করার চেষ্টা করছি।

তবে বিভিন্ন পদ্ধতি বিভিন্ন ফলাফল এবং ত্রুটি কোড উত্পাদন করতে পারে তবে ফলাফল অবজেক্টটি একইভাবে ইনস্ট্যান্ট করা হবে।

কিছুটা সময় সাশ্রয় করতে এবং সি # তে অ্যাসিঙ্ক / দক্ষতার জন্য অপেক্ষা করার বিষয়ে আরও জানার জন্য, আমি আমার ওয়েব এপিআই ক্রিয়াকলাপের সমস্ত পদ্ধতি বডিগুলিকে একটি অ্যাসিঙ্ক্রোনাস অ্যাকশন প্রতিনিধিতে গুটিয়ে রাখার চেষ্টা করছি তবে কিছুটা ফাঁকে ধরা পড়ে ...

নিম্নলিখিত ক্লাস দেওয়া:

public class Result
{
    public bool Success { get; set; }
    public List<int> ErrorCodes{ get; set; }
}

public async Task<Result> GetResultAsync()
{
    return await DoSomethingAsync<Result>(result =>
    {
        // Do something here
        result.Success = true;

        if (SomethingIsTrue)
        {
            result.ErrorCodes.Add(404);
            result.Success = false;
        }
    }
}

আমি এমন একটি পদ্ধতি লিখতে চাই যা ফলাফল ফলাফলের উপর কোনও ক্রিয়া সম্পাদন করে তা ফিরিয়ে দেয়। সাধারণত সিঙ্ক্রোনাস পদ্ধতিগুলির মাধ্যমে এটি হত

public T DoSomethingAsync<T>(Action<T> resultBody) where T : Result, new()
{
    T result = new T();
    resultBody(result);
    return result;
}

তবে কীভাবে আমি এই পদ্ধতিটি async / প্রতীক্ষা করে অ্যাসিক্রোনাস পদ্ধতিতে রূপান্তর করব?

এটি আমি চেষ্টা করেছি:

public async Task<T> DoSomethingAsync<T>(Action<T, Task> resultBody) 
    where T: Result, new()
{
    // But I don't know what do do from here.
    // What do I await?
}

1
আপনি যদি newআপ-আপ করে Tথাকেন তবে আপনার পদ্ধতিটি কেন অ্যাসিঙ্ক্রোনাস হওয়া দরকার? অ্যাসিঙ্ক্রোনাস এপিআই ব্যবহার করে কোডে আফাইক , আপনার কেবল asyncঅন্য ব্যবহারের পদ্ধতিগুলি থেকে নীড় প্রচার করতে হবে।
মিলিমুজ

দুঃখিত আমি এখনও এটির জন্য মোটামুটি নতুন, আপনি যখন কেবলমাত্র প্রচারের প্রয়োজন বলছেন তখন আপনার অর্থ কী এবং টি-র সাথে নতুন করে যুক্ত করার কী দরকার?
Albin Anke

আমি মনে করি আমি এটি আবিষ্কার করেছি, ধন্যবাদ মিলিমুজ আপনি আমাকে কিছু চিন্তা করার জন্য দিয়েছেন।
Albin Anke

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

1
@ অ্যালবিনএঙ্ক "প্রচার" করার অর্থ আমার অর্থ যে আপনি যদি কোনও পদ্ধতির মতো একটি নেট নেটওয়ার্ক কল করে থাকেন তবেStream.ReadAsync() সেই পদ্ধতিটি নিজেই অবিচ্ছিন্ন হওয়া উচিত এবং আপনি Task<T>যেখানে Tফিরে এসেছিলেন সেখানে পদ্ধতিটি সমকালীন হবে return ধারণাটি হ'ল এইভাবে, আপনার পদ্ধতির প্রত্যেক কলার অন্তর্নিহিতটি Stream.ReadAsync()সম্পূর্ণ করার জন্য "অবিচ্ছিন্নভাবে অপেক্ষা করুন" (এটির জন্য ভাল শব্দটি কী তা আমি জানি না) can আপনি যেটির জন্য এটি ব্যবহার করতে পারেন তার একটি রূপক হ'ল অ্যাসিঙ্কটি "সংক্রামক" এবং নিম্ন-স্তরের অন্তর্নির্মিত আই / ও থেকে অন্য কোডে ছড়িয়ে পড়ে যার ফলাফলগুলি I / O এর উপর নির্ভর করে।
মিলিমুজ

উত্তর:


307

asyncসমতুল্য Action<T>হয় Func<T, Task>, তাই আমি বিশ্বাস করি এই আপনি যা খুঁজছেন তা হল:

public async Task<T> DoSomethingAsync<T>(Func<T, Task> resultBody)
    where T : Result, new()
{
  T result = new T();
  await resultBody(result);
  return result;
}

@ স্টেফেন স্পষ্টতই আমি এমভিভিএম লিগথ মেসেঞ্জারে কিছু অনুরূপ বাস্তবায়নের চেষ্টা করছি, আমি কি একইভাবে বাস্তবায়ন করতে পারি?
জুয়ান পাবলো গোমেজ

@ জুয়ানপাবলো গোমেজ: আমি তাদের ধরণের বার্তাগুলির সাথে পরিচিত নই, তবে কেন এটি কার্যকর হবে না তা আমি দেখতে পাচ্ছি না।
স্টিফেন ক্লিয়ারি

1
এটা চমৎকার! আমি ভেবেছিলাম একটি অ্যাসিঙ্ক অ্যাকশন করা সম্ভব হবে না এবং ইতিমধ্যে এটি একটি ভাষার ত্রুটি হিসাবে বিবেচনা করেছে। আমি ফানক ব্যবহারের কথা ভাবি নি। ধন্যবাদ।
নোয়েল ওয়াইডার

2
@ ডিএফএসএফট: একটি voidপদ্ধতির Taskঅ্যাসিঙ্ক সমতুল্য একটি পুনরুদ্ধার পদ্ধতি; এভাবে এর ASYNC সমতুল্য Actionহয় Func<Task>, এবং ASYNC সমতুল্য Action<T>হয় Func<T, Task>। আরও তথ্য এখানে
স্টিফেন ক্লিয়ারি

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

-11

সুতরাং আমি বিশ্বাস করি এটি বাস্তবায়নের উপায় হ'ল:

public Task<T> DoSomethingAsync<T>(Action<T> resultBody) where T : Result, new()
{
    return Task<T>.Factory.StartNew(() =>
    {
        T result = new T();
        resultBody(result);
        return result;
    });
}

7
আপনার এএসপি.নেটে Task.Run(এবং আরও অনেক কিছু StartNew) এড়ানো উচিত ।
স্টিফেন ক্লিয়ারি

এটি করার একটি ভাল উপায় কি?
Albin Anke

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