ইন্টারফেস বাস্তবায়ন async করা


116

আমি বর্তমানে কয়েকটি অ্যাসিঙ্ক পদ্ধতি ব্যবহার করে আমার অ্যাপ্লিকেশনটি তৈরি করার চেষ্টা করছি। আমার সমস্ত আইও একটি ইন্টারফেসের সুস্পষ্ট বাস্তবায়নের মাধ্যমে সম্পন্ন হয়েছে এবং কীভাবে অপারেশনগুলিকে অ্যাসিঙ্ক করা যায় সে সম্পর্কে আমি কিছুটা বিভ্রান্ত।

আমি জিনিসগুলি দেখতে পাই বাস্তবায়নে আমার কাছে দুটি বিকল্প রয়েছে:

interface IIO
{
    void DoOperation();
}

বিকল্প 1: একটি অন্তর্নিহিত বাস্তবায়ন async করুন এবং অন্তর্নিহিত বাস্তবায়নের ফলাফলের জন্য অপেক্ষা করুন।

class IOImplementation : IIO
{

     async void DoOperation()
    {
        await Task.Factory.StartNew(() =>
            {
                //WRITING A FILE OR SOME SUCH THINGAMAGIG
            });
    }

    #region IIO Members

    void IIO.DoOperation()
    {
        DoOperation();
    }

    #endregion
}

বিকল্প 2: সুস্পষ্ট বাস্তবায়ন async করুন এবং অন্তর্নিহিত বাস্তবায়ন থেকে কার্যটির জন্য অপেক্ষা করুন।

class IOAsyncImplementation : IIO
{
    private Task DoOperationAsync()
    {
        return new Task(() =>
            {
                //DO ALL THE HEAVY LIFTING!!!
            });
    }

    #region IIOAsync Members

    async void IIO.DoOperation()
    {
        await DoOperationAsync();
    }

    #endregion
}

এই বাস্তবায়নগুলির মধ্যে একটির কি অন্যের চেয়ে ভাল বা এমন কোনও উপায় আছে যা আমি ভাবছি না?

উত্তর:


231

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

আপনাকে যা করতে হবে তা হ'ল ইন্টারফেসটি পরিবর্তন করা , যাতে এটি অ্যাসিনক্রোনাস হয়:

interface IIO
{
    Task DoOperationAsync(); // note: no async here
}

class IOImplementation : IIO
{
    public async Task DoOperationAsync()
    {
        // perform the operation here
    }
}

এইভাবে, ব্যবহারকারী দেখতে পাবেন যে অপারেশনটি রয়েছে asyncএবং তারা এতে সক্ষম হবেন await। এটি আপনার কোড ব্যবহারকারীদের স্যুইচ করতে বাধ্য করে async, তবে এটি অনিবার্য।

এছাড়াও, আমি ধরে নিচ্ছি যে StartNew()আপনার বাস্তবায়নে ব্যবহার করা কেবল একটি উদাহরণ, আপনার অ্যাসিঙ্ক্রোনাস আইও প্রয়োগ করতে হবে না। (এবং new Task()এমনকি খারাপ হয়, যে এমনকি কাজ করবে না, কারণ আপনি না ।)Start()Task


এটি সুস্পষ্ট বাস্তবায়নের সাথে কীভাবে দেখবে? এছাড়াও, আপনি এই বাস্তবায়নের জন্য কোথায় অপেক্ষা করছেন?
মরিয়া

1
@Animal স্পষ্ট বাস্তবায়ন একই হিসাবে সবসময় (শুধু যোগ দেখাবে async): async Task IIO.DoOperationAsync()। এবং আপনি যেখানে awaitফিরে এসেছেন মানে Task? আপনি যেখানেই ফোন করুন DoOperationAsync()
সোভিক

মূলত আমি মনে করি আমি আমার প্রশ্নটি "আমি কোথায় অপেক্ষা করব?" যদি আমি অ্যাসিঙ্ক পদ্ধতিতে অপেক্ষা না করি তবে আমি সংকলনের সতর্কতা পেয়েছি।
মরিয়া

1
আদর্শভাবে, আপনার আইও কোডটি মোড়ানো প্রয়োজন হবে না Task.Run(), যে আইও কোডটি নিজেই অবিচ্ছিন্ন হওয়া উচিত এবং আপনি awaitসরাসরি এটি করতে পারেন। যেমন line = await streamReader.ReadLineAsync()
সুইভ

4
তারপরে আপনার কোডকে অ্যাসিঙ্ক করার পক্ষে খুব বেশি কিছু নেই। নিবন্ধটি দেখুন আমি কি সিঙ্ক্রোনাস পদ্ধতির জন্য অ্যাসিনক্রোনাস মোড়ক উন্মোচন করা উচিত?
সুইভ

19

অ্যাসিঙ্ক ক্রিয়াকলাপগুলির জন্য আরও একটি ইন্টারফেস চালু করা আরও ভাল সমাধান। নতুন ইন্টারফেস অবশ্যই মূল ইন্টারফেস থেকে উত্তরাধিকারী হতে হবে।

উদাহরণ:

interface IIO
{
    void DoOperation();
}

interface IIOAsync : IIO
{
    Task DoOperationAsync();
}


class ClsAsync : IIOAsync
{
    public void DoOperation()
    {
        DoOperationAsync().GetAwaiter().GetResult();
    }

    public async Task DoOperationAsync()
    {
        //just an async code demo
        await Task.Delay(1000);
    }
}


class Program
{
    static void Main(string[] args)
    {
        IIOAsync asAsync = new ClsAsync();
        IIO asSync = asAsync;

        Console.WriteLine(DateTime.Now.Second);

        asAsync.DoOperation();
        Console.WriteLine("After call to sync func using Async iface: {0}", 
            DateTime.Now.Second);

        asAsync.DoOperationAsync().GetAwaiter().GetResult();
        Console.WriteLine("After call to async func using Async iface: {0}", 
            DateTime.Now.Second);

        asSync.DoOperation();
        Console.WriteLine("After call to sync func using Sync iface: {0}", 
            DateTime.Now.Second);

        Console.ReadKey(true);
    }
}

পিএস আপনার অ্যাসিঙ্ক অপারেশনগুলিকে পুনরায় ডিজাইন করুন যাতে তারা শূন্যতার পরিবর্তে টাস্কটি ফিরিয়ে দেয়, যদি না আপনার সত্যিকার অর্থে শূন্যতা ফিরে আসে।


5
GetAwaiter().GetResult()তার বদলে কেন হবে না Wait()? এই ভাবে আপনাকে AggregateExceptionঅভ্যন্তরীণ ব্যতিক্রম আনতে কোনও আনপ্যাক করার দরকার নেই ।
Tagc

একটি বৈচিত্র বর্গ বাস্তবায়নে একাধিক উপর নির্ভর (সম্ভবত স্পষ্ট) ইন্টারফেসের হল: class Impl : IIO, IIOAsync। IIO এবং IIOAsync নিজেরাই, তবে, বিভিন্ন চুক্তি যা 'পুরানো চুক্তিগুলি' আরও নতুন কোডে টানতে পারে। var c = new Impl(); IIOAsync asAsync = c; IIO asSync = c
ব্যবহারকারী 2864740
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.