AsyncDispose এ ব্যতিক্রমগুলি মোকাবেলা করার সঠিক উপায়


20

নতুন। নেট কোর 3 এর দিকে স্যুইচ করার সময় IAsynsDisposable, আমি নিম্নলিখিত সমস্যাটিতে হোঁচট খেয়েছি।

সমস্যার মূল বিষয়: যদি DisposeAsyncকোনও ব্যতিক্রম ছুঁড়ে ফেলা হয়, তবে এই ব্যতিক্রমটি await usingব্লক-এর ভিতরে ফেলে দেওয়া কোনও ব্যতিক্রম লুকায় ।

class Program 
{
    static async Task Main()
    {
        try
        {
            await using (var d = new D())
            {
                throw new ArgumentException("I'm inside using");
            }
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message); // prints I'm inside dispose
        }
    }
}

class D : IAsyncDisposable
{
    public async ValueTask DisposeAsync()
    {
        await Task.Delay(1);
        throw new Exception("I'm inside dispose");
    }
}

যা ধরা পড়ছে তা হ'ল নিক্ষেপ করা হলে তা গ্রহণযোগ্যতা এবং নিক্ষেপ না করলে কেবল AsyncDisposeভিতরে থেকে ব্যতিক্রম ।await usingAsyncDispose

তবে আমি এটি অন্য উপায়ে পছন্দ করবো: await usingযদি সম্ভব হয় তবে ব্লক থেকে ব্যতিক্রম পাওয়া এবং DisposeAsync- await usingব্লকটি সফলভাবে শেষ হলেই ব্যতিক্রম ।

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

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


আমি জানি যে অ-অ্যাসিঙ্ক ক্ষেত্রে একই সমস্যা রয়েছে: ব্যতিক্রমটি ব্যতিক্রমগুলিকে finallyওভাররাইড করে try, তাই এটিকে নিক্ষেপ করার প্রস্তাব দেওয়া হয় না Dispose()। তবে নেটওয়ার্ক অ্যাক্সেস করার ক্লাসগুলি বন্ধ করার পদ্ধতিগুলিতে ব্যতিক্রমগুলি দমন করা মোটেই ভাল দেখাচ্ছে না।


নিম্নলিখিত সহায়িকার সাহায্যে সমস্যাটি নিয়ে কাজ করা সম্ভব:

static class AsyncTools
{
    public static async Task UsingAsync<T>(this T disposable, Func<T, Task> task)
            where T : IAsyncDisposable
    {
        bool trySucceeded = false;
        try
        {
            await task(disposable);
            trySucceeded = true;
        }
        finally
        {
            if (trySucceeded)
                await disposable.DisposeAsync();
            else // must suppress exceptions
                try { await disposable.DisposeAsync(); } catch { }
        }
    }
}

এবং এটি পছন্দ করুন

await new D().UsingAsync(d =>
{
    throw new ArgumentException("I'm inside using");
});

যা একধরণের কুৎসিত (এবং ব্যবহারের ব্লকের অভ্যন্তরে প্রারম্ভিক রিটার্নের মতো জিনিসগুলি অস্বীকার করে)।

await usingযদি সম্ভব হয় তবে একটি ভাল, প্রমিত সমাধান আছে ? ইন্টারনেটে আমার অনুসন্ধান এমনকি এই সমস্যাটি নিয়ে আলোচনা করে না।


1
" তবে নেটওয়ার্ক অ্যাক্সেসের ক্লাসগুলি বন্ধ করার পদ্ধতিগুলিতে ব্যতিক্রমগুলি দমন করা মোটেই ভাল লাগে না " - আমি মনে করি বেশিরভাগ নেটওয়ার্ক বিএলসি ক্লাসগুলির Closeএই কারণেই আলাদা পদ্ধতি রয়েছে method এটি একইভাবে করা সম্ভবত বুদ্ধিমান: CloseAsyncজিনিসগুলি সুন্দরভাবে বন্ধ করার চেষ্টা করে এবং ব্যর্থতার দিকে ছুড়ে দেয়। DisposeAsyncশুধু এটি সেরা করে তোলে, এবং নিঃশব্দে ব্যর্থ হয়।
canton7

@ ক্যান্টন:: ভাল, একটি পৃথক CloseAsyncঅর্থ হ'ল এটি চালানোর জন্য আমার অতিরিক্ত সতর্কতা অবলম্বন করা উচিত। আমি যদি এটি কেবল using-ব্লকের শেষে রাখি তবে তা প্রাথমিক রিটার্ন ইত্যাদিতে এড়িয়ে যাবে। (এটিই আমরা ঘটতে চাই) এবং ব্যতিক্রমগুলি (এটিই আমরা ঘটতে চাইব)। তবে ধারণাটি আশাব্যঞ্জক বলে মনে হচ্ছে।
ভ্লাদ

অনেক কোডিং স্ট্যান্ডার্ডগুলি প্রাথমিক রিটার্ন নিষিদ্ধ করার একটি কারণ রয়েছে :) যেখানে নেটওয়ার্কিং জড়িত সেখানে কিছুটা স্পষ্ট হওয়া কোনও খারাপ জিনিস নয় আইএমও। Disposeসবসময়ই ছিল "বিষয়গুলি ভুল হতে পারে: পরিস্থিতি উন্নতির জন্য আপনার যথাসাধ্য চেষ্টা করুন, তবে আরও খারাপ করবেন না", এবং কেন এর AsyncDisposeচেয়ে আলাদা হওয়া উচিত তা আমি দেখছি না ।
ক্যান্টন 7

@ ক্যান্টন:: ঠিক আছে, একটি ভাষা-ব্যাতিক্রমগুলিতে প্রতিটি বিবৃতি প্রথম দিকে ফিরে আসতে পারে: - \
ভ্লাদ

ঠিক আছে, তবে সেগুলি ব্যতিক্রমী হবে । সেক্ষেত্রে, উপার্জন DisposeAsyncআপ পরিপাটি তার যথাসাধ্য চেষ্টা কিন্তু নিক্ষেপ করার অধিকার জিনিস। আপনি ইচ্ছাকৃত তাড়াতাড়ি রিটার্নের বিষয়ে কথা বলছিলেন , যেখানে ইচ্ছাকৃত তাড়াতাড়ি প্রত্যাবর্তন ভুল করে কোনও কলকে বাইপাস করতে পারে CloseAsync: এগুলি হ'ল অনেক কোডিং মানক দ্বারা নিষিদ্ধ।
ক্যান্টন 7

উত্তর:


3

এমন কিছু ব্যতিক্রম রয়েছে যেগুলি আপনি পৃষ্ঠভূমি করতে চান (বর্তমান অনুরোধটিকে বাধাগ্রস্থ করুন, বা প্রক্রিয়াটি নামিয়ে আনুন), এবং এমন ব্যতিক্রম রয়েছে যেগুলি আপনার নকশাটি কখনও কখনও ঘটবে এবং আপনি সেগুলি পরিচালনা করতে পারেন (যেমন: চেষ্টা করুন এবং চালিয়ে যান)।

তবে এই দুটি ধরণের মধ্যে পার্থক্যটি কোডের চূড়ান্ত কলারের উপর নির্ভর করে - সিদ্ধান্তটিকে কলারের কাছে ছেড়ে দেওয়াটাই ব্যতিক্রমের পুরো বিষয়টি এটি।

কখনও কখনও কলার আসল কোড ব্লক থেকে ব্যতিক্রমটিকে সাফ্যাক্স করার উপর আরও বেশি অগ্রাধিকার দেবে এবং কখনও কখনও ব্যতিক্রমটি ব্যতিক্রম Dispose। কোনটিকে অগ্রাধিকার দেওয়া উচিত তা সিদ্ধান্ত নেওয়ার পক্ষে কোনও সাধারণ নিয়ম নেই। সিএনআর সিঙ্ক এবং অ-অ্যাসিঙ্ক আচরণের মধ্যে অন্তত সামঞ্জস্যপূর্ণ (যেমন আপনি উল্লেখ করেছেন) is

এটি সম্ভবত দুর্ভাগ্য যে এখন আমাদের AggregateExceptionএকাধিক ব্যতিক্রম উপস্থাপন করতে হবে, এটি সমাধান করার জন্য এটি পুনরায় তৈরি করা যাবে না। অর্থাত্ যদি কোনও ব্যতিক্রম ইতিমধ্যে ফ্লাইটে থাকে এবং অন্যটি নিক্ষেপ করা হয় তবে সেগুলি একটিতে যুক্ত করা হয় AggregateExceptioncatchপ্রক্রিয়া তাই পরিবর্তিত হতে পারে যে যদি আপনি লিখতে catch (MyException)তারপর এটি কোন ফেলবো AggregateExceptionযে ধরনের একটি ব্যতিক্রম রয়েছে MyException। যদিও এই ধারণাটি থেকে উদ্ভূত আরও বিভিন্ন জটিলতা রয়েছে এবং এখন এত মৌলিক কিছু সংশোধন করা খুব ঝুঁকিপূর্ণ।

আপনি UsingAsyncকোনও মূল্যের প্রথম দিকে ফিরে আসার জন্য সমর্থন করতে নিজের উন্নতি করতে পারেন:

public static async Task<R> UsingAsync<T, R>(this T disposable, Func<T, Task<R>> task)
        where T : IAsyncDisposable
{
    bool trySucceeded = false;
    R result;
    try
    {
        result = await task(disposable);
        trySucceeded = true;
    }
    finally
    {
        if (trySucceeded)
            await disposable.DisposeAsync();
        else // must suppress exceptions
            try { await disposable.DisposeAsync(); } catch { }
    }
    return result;
}

সুতরাং আমি কি সঠিক বুঝতে পারি: আপনার ধারণাটি হ'ল কিছু ক্ষেত্রে কেবলমাত্র স্ট্যান্ডার্ড await usingব্যবহার করা যেতে পারে (এটি যেখানে ডিসপোজএেন্সিকটি মারাত্মক ক্ষেত্রে ফেলবে না) এবং এর মতো সহায়ক UsingAsyncআরও উপযুক্ত (যদি ডিসপোজএেন্সিক ছুঁড়ে মারার সম্ভাবনা থাকে) ? (অবশ্যই, আমাকে সংশোধন করতে হবে UsingAsyncযাতে এটি অন্ধভাবে সমস্ত কিছু ধরে না, তবে কেবল অ-প্রাণঘাতী (এবং এরিক লিপার্টের ব্যবহারে অস্থিহীন নয় )
ভ্লাদ

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

4

কেন আপনি এটি ইতিমধ্যে বুঝতে পেরেছেন তবে এটি বানানটি মূল্যবান। এই আচরণটি নির্দিষ্ট নয় await using। এটি একটি সরল usingব্লক দিয়ে ঘটবে । আমি Dispose()এখানে বলার সময় এটি সমস্ত ক্ষেত্রে প্রযোজ্য DisposeAsync()

একটি usingব্লক একটি try/ finallyব্লকের জন্য কেবল সিনট্যাকটিকাল চিনি , যেমন ডকুমেন্টেশনের মন্তব্য অংশটি বলেছে। আপনি যা দেখেন তা ঘটে যায় কারণ একটি ব্যতিক্রম পরেও finallyব্লকটি সর্বদা চলমান। সুতরাং যদি কোনও ব্যতিক্রম ঘটে এবং সেখানে কোনও catchব্লক না থাকে তবে finallyব্লকটি চলমান অবধি ব্যতিক্রমটি আটকে রাখা হয় এবং তারপরে ব্যতিক্রমটি ছুঁড়ে দেওয়া হয়। তবে যদি কোনও ব্যতিক্রম ঘটে যায় তবে finallyআপনি কখনই পুরানো ব্যতিক্রম দেখতে পাবেন না।

আপনি এই উদাহরণ সহ এটি দেখতে পারেন:

try {
    throw new Exception("Inside try");
} finally {
    throw new Exception("Inside finally");
}

এটি ভিতরে Dispose()বা DisposeAsync()বলা হয় তা বিবেচনা করে না finally। আচরণও একই রকম।

আমার প্রথম চিন্তা হ'ল: throwোকাও না Dispose()। তবে মাইক্রোসফ্টের নিজস্ব কিছু কোড পর্যালোচনা করার পরে, আমি মনে করি এটি নির্ভর করে।

FileStreamউদাহরণস্বরূপ, তাদের বাস্তবায়নটি একবার দেখুন । উভয় সিঙ্ক্রোনাস Dispose()পদ্ধতি এবং DisposeAsync()আসলে ব্যতিক্রম ছুঁড়ে ফেলতে পারে। সিঙ্ক্রোনাস কিছু ব্যতিক্রম ইচ্ছাকৃতভাবে উপেক্ষাDispose() করে না , তবে সব কিছু নয়।

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

যাইহোক, অন্যান্য ধরণের অবজেক্টগুলিতে, আপনি যখন কল করেন তখন Dispose()আপনার সত্যিকার অর্থে অবজেক্টটির কোনও ব্যবহার হয় না। কল Dispose()করার অর্থ হ'ল "এই জিনিসটি আমার কাছে মারা গেছে"। হতে পারে এটি কিছু বরাদ্দ মেমরি পরিষ্কার করে, তবে ব্যর্থতা কোনওভাবেই আপনার অ্যাপ্লিকেশনটির ক্রিয়াকলাপকে প্রভাবিত করে না। সেক্ষেত্রে আপনি নিজের মধ্যে থাকা ব্যতিক্রমটিকে উপেক্ষা করার সিদ্ধান্ত নিতে পারেন Dispose()

কিন্তু যাই হোক, আপনি যদি ভিতরে একটি ব্যতিক্রম মধ্যে পার্থক্য করতে চান usingবা একটি ব্যতিক্রম যে থেকে এসেছেন Dispose(), তাহলে আপনি একটি প্রয়োজন try/ catchঅভ্যন্তরে ও আপনার বাইরে ব্লক usingব্লক:

try {
    await using (var d = new D())
    {
        try
        {
            throw new ArgumentException("I'm inside using");
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message); // prints I'm inside using
        }
    }
} catch (Exception e) {
    Console.WriteLine(e.Message); // prints I'm inside dispose
}

অথবা আপনি ঠিক ব্যবহার করতে পারেন না using। একটি try/ catch/ finallyনিজেকে ব্লক করুন, যেখানে আপনি কোনও ব্যতিক্রম ধরা পড়ে finally:

var d = new D();
try
{
    throw new ArgumentException("I'm inside try");
}
catch (Exception e)
{
    Console.WriteLine(e.Message); // prints I'm inside try
}
finally
{
    try
    {
        if (D != null) await D.DisposeAsync();
    }
    catch (Exception e)
    {
        Console.WriteLine(e.Message); // prints I'm inside dispose
    }
}

3
বিটিডব্লিউ , সোর্স.ডটনাটনেট (। নেট কোর) / রেফারেন্সসোর্স.মাইক্রোসফট.কম (। নেট ফ্রেমওয়ার্ক) ব্রাউজ করা অনেক সহজ গিটহাবের চেয়ে
ক্যান্টন 7

আপনার উত্তর করার জন্য আপনাকে ধন্যবাদ! আমি জানি আসল কারণটি কী (আমি চেষ্টা / শেষ পর্যন্ত এবং প্রশ্নে সিঙ্ক্রোনাস কেসটি উল্লেখ করেছি)। এখন আপনার প্রস্তাব সম্পর্কে। একজন catch ভিতরেusing ব্লক would সাহায্যের না, কারণ সাধারণত ব্যতিক্রম হ্যান্ডলিং কোথাও দূর থেকে সম্পন্ন করা হয় usingব্লক নিজেই, তাই এটি ভিতরে হ্যান্ডলিং usingসাধারণত খুব কার্যকর হয়। না ব্যবহার সম্পর্কে using- এটি কি প্রস্তাবিত কাজের চেয়ে ভাল?
ভ্লাদ

2
@ ক্যান্টন 7 দুর্দান্ত! আমি রেফারেন্সসোর্স.মাইক্রোসফট.কম সম্পর্কে সচেতন ছিলাম , তবে জানি না। নেট কোরের সমতুল্য কোনটি আছে। ধন্যবাদ!
গ্যাব্রিয়েল লুসি

@ ভ্লাদ "ভাল" এমন কিছু যা কেবল আপনি উত্তর দিতে পারেন। আমি জানি যদি আমি অন্য কারো কোড পড়া ছিল, আমি এইজন্য পছন্দ করেন try/ catch/ finallyব্লক যেহেতু এটি অবিলম্বে হবে পরিষ্কার কি এটা পড়তে কি যেতে না করেও করছে AsyncUsingকরছে। আপনি প্রথম দিকে রিটার্ন করার বিকল্পটিও রাখেন keep এছাড়াও আপনার অতিরিক্ত সিপিইউ খরচ হবে AwaitUsing। এটি ছোট হবে, তবে এটি আছে।
গ্যাব্রিয়েল লুসি

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

4

ব্যবহার করা কার্যকরভাবে ব্যতিক্রম হ্যান্ডলিং কোড (চেষ্টা করার সিনট্যাক্স চিনি ... অবশেষে ... নিষ্পত্তি ())।

যদি আপনার ব্যতিক্রম হ্যান্ডলিং কোড ব্যতিক্রম ছুঁড়ে ফেলেছে, তবে কিছু কিছু রোয়ালি আপ করা হয়েছে।

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

ব্যতিক্রম শ্রেণিবিন্যাসের উপর নির্ভর করে আপনার ব্যতিক্রম হ্যান্ডলিং / ডিপোজ কোডটি যদি ব্যতিক্রম ছুঁড়ে ফেলে তবে আপনার যা করা উচিত তা হল:

মারাত্মক, অস্থিযুক্ত এবং ভেক্সিংয়ের জন্য সমাধানটি একই।

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

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

আমি তাদের অবহিত করার চেষ্টা করতে পারেন। কিন্তু সার্ভার / এফএস সাইডে স্টাফ পরিষ্কার করছেন? এটা কী তাদের সময় সমাপ্ত এবং তাদের ব্যতিক্রম হ্যান্ডলিং জন্য দায়ী।


সুতরাং আপনার প্রস্তাবটি কার্যকরভাবে সংযোগের ব্যতিক্রমগুলি ব্যতিক্রমকে দমন করতে উত্সাহিত করে, তাই না?
ভ্লাদ

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

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

@ ভ্লাইড মারাত্মক ব্যতিক্রম সম্ভাবনা? আমাদের অলসাসিদের ঝুঁকিপূর্ণ হতে হবে এবং এগুলি কখনই "কল ডিসপোজ" এর বাইরে পরিচালনা করা উচিত নয়। এবং আসলে তাদের সাথে কিছু করা উচিত নয়। এগুলি আসলে কোনও ডকুমেন্টেশনে উল্লেখ ছাড়াই চলে। | হাড় মাথায় ব্যতিক্রম? সর্বদা তাদের ঠিক করুন। | ট্রিপ পার্সে () | এর মতো গিলে / হ্যান্ডলিংয়ের প্রধান প্রার্থীরা ভেক্সিং ব্যতিক্রম candidates Exogenous? সর্বদা হ্যান্ডেল করা উচিত। প্রায়শই আপনি তাদের সম্পর্কে ব্যবহারকারীকে বলতে এবং তাদের লগ করতে চান। তবে অন্যথায়, তারা আপনার প্রক্রিয়াটি মেরে ফেলার যোগ্য নয়।
ক্রিস্টোফার

@ ভ্ল্যাড আমি সিকিএল সংযোগটি দেখলাম is ডিসপোজ ()। এটি এমনকি নেই পরোয়া কানেকশনে হচ্ছে সার্ভার কিছু পাঠান। NativeMethods.UnmapViewOfFile();এবং এর ফলে এখনও কিছু হতে পারে NativeMethods.CloseHandle()। তবে সেগুলি বহির্মুখী থেকে আমদানি করা হয়। কোনও রিটার্নের মান বা অন্য কোনও কিছুর যাচাই বাছাই করা হয়নি যা সঠিক .NET ব্যতিক্রম those দু'জনের মুখোমুখি হতে পারে তার চারপাশে। সুতরাং আমি দৃ strongly়ভাবে asuming করছি, SQLlConnection.Dispose (bool) কেবল যত্ন করে না। | ক্লোজ আসলে অনেক সুন্দর, আসলে সার্ভারটি বলছে telling এটি নিষ্পত্তি কল করার আগে।
ক্রিস্টোফার

1

আপনি AggregateException ব্যবহার করার চেষ্টা করতে পারেন এবং আপনার কোডটিকে এরকম কিছু সংশোধন করতে পারেন:

class Program 
{
    static async Task Main()
    {
        try
        {
            await using (var d = new D())
            {
                throw new ArgumentException("I'm inside using");
            }
        }
        catch (AggregateException ex)
        {
            ex.Handle(inner =>
            {
                if (inner is Exception)
                {
                    Console.WriteLine(e.Message);
                }
            });
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
        }
    }
}

class D : IAsyncDisposable
{
    public async ValueTask DisposeAsync()
    {
        await Task.Delay(1);
        throw new Exception("I'm inside dispose");
    }
}

https://docs.microsoft.com/ru-ru/dotnet/api/system.aggregateexception?view=netframework-4.8

https://docs.microsoft.com/ru-ru/dotnet/standard/parallel-programming/exception-handling-task-parallel-library

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