AMcoder - javascript, python, java, html, php, sql

Ինչու՞ պետք է կիրառեք IDisposable-ը միայն չկառավարվող ռեսուրսները մաքրելու համար:

փաստաթղթերը ասում է

Դուք պետք է կիրառեք IDisposable-ը միայն այն դեպքում, եթե ձեր տեսակն ուղղակիորեն օգտագործում է չկառավարվող ռեսուրսներ:

Գալով հիմնականում Java ֆոնից, սա ինձ համար տարօրինակ է թվում: Ենթադրենք, ես ունեմ դաս, որը պարունակում է IDdisposable անդամ.

class Foo : IDisposable {
    private StreamWriter sw;
    ...
}

... և ենթադրենք, որ այս դասը օգտագործվում է, օրինակ, որպես մի տեսակ զտիչ, որը վերցնում է տողերը և փոփոխում դրանք, այնուհետև դրանք դուրս է բերում StreamWriter sw-ով: Ես ուզում եմ այս դասը օգտագործել գրողի պես:

Ինչու ես չէի ցանկանա իրականացնել Dispose(bool)-ը, որը կկոչեր sr.Dispose()? Սա այն է, ինչ ես պետք է անեի, եթե այն կոդավորեի Java-ում (Java Closable ինտերֆեյսը նման է .NET-ի IDisposable-ին, թեև որոշ առումներով տարբերվում է): Այնուամենայնիվ, փաստաթղթերում ասվում է, որ ես չպետք է օգտագործեմ, քանի որ ես ուղղակիորեն չեմ օգտագործում չկառավարվող ռեսուրսները:

Եթե ​​ես չշրջանցեմ Dispose(bool)-ը, ինչպե՞ս է տնօրինվում sw ռեսուրսը, երբ ես հեռանում եմ using հայտարարությամբ սկսված բլոկից:

19.02.2018

  • @AntoinePelletier աղբահանը մաքրում է միայն կառավարվող ռեսուրսները: Այն չգիտի չկառավարվող ռեսուրսների մասին: Ահա թե ինչու մենք սկզբում ունենք IDisposable ինտերֆեյսը: 19.02.2018

Պատասխանները:


1

Դուք պետք է իրականացնեք IDisposable-ը, երբ ձեր դասը պարունակում է IDisposable դաշտ, ինչպիսին օրինակ StreamWriterն է:

Այս դեպքում կարող եք ենթադրել, որ ձեր տեսակը օգտագործում է չկառավարվող ռեսուրսներ (StreamWriter դասի միջոցով) գլխարկի տակ, և դուք միշտ պետք է հեռացնեք ցանկացած օբյեկտ, որն իրականացնում է IDisposable ինտերֆեյսը, հենց որ ավարտեք դրանք օգտագործելը:

Ինչո՞ւ ես չեմ ցանկանա իրականացնել IDisposable(bool)ը, որը կկոչեր sr.Dispose():

Դուք, անշուշտ, կցանկանայիք:

Եթե ​​ես չշրջանցեմ Dispose(bool)-ը, ինչպե՞ս է կառավարվող sw ռեսուրսը ոչնչացվում, երբ ես հեռանում եմ using հայտարարությամբ սկսված բլոկից:

Դա չի նշանակում: Հիմքում ընկած չկառավարվող ռեսուրսը (ներ)ը կարող է ի վերջո թողարկվել վերջնականացուցիչի կողմից (կախված IDisposable դասի իրականացումից), սակայն կառավարվող օբյեկտը չի հեռացվի, քանի դեռ դուք բացահայտորեն չեք օգտագործում այն ​​ձեր դասարանում:

19.02.2018
  • Շնորհակալություն, ես նույնպես այդպես մտածեցի: Այսպիսով, ինչու՞ է Microsoft-ն ասում, Դուք պետք է կիրառեք IDisposable-ը միայն այն դեպքում, եթե ձեր տեսակն օգտագործում է չկառավարվող ռեսուրսներ ուղղակի, այլ ոչ թե ասում է, որ դուք պետք է կիրառեք այն, նույնիսկ եթե այն օգտագործում է ռեսուրսներ գլխարկի տակ: 19.02.2018
  • Ես չեմ կարող պատասխանել դրան, քանի որ ես չեմ գրել փաստաթղթերը :) Բայց ենթադրում եմ, որ դրանք նկատի ունեն, որ դուք օգտագործում եք չկառավարվող ռեսուրսները անմիջապես միջոցով IDdisposable օրինակի միջոցով: Եթե ​​նայեք այստեղ, ասվում է, որ դուք պետք է կիրառեք «Հիմնական հեռացման օրինակը» միանգամյա օգտագործման տեսակների օրինակներ պարունակող տեսակների վրա՝ docs.microsoft.com/en-us/dotnet/standard/design-guidelines/: 19.02.2018
  • @mm8 Կներեք, բայց դա անհեթեթություն է: Դա ուղղակիորեն վերաիմաստավորվում է անուղղակի իմաստով: Ճիշտ պատասխանն այն է, որ MS փաստաթղթերն այստեղ ուղղակի սխալ են: :) 19.02.2018
  • @hvd: Ես քեզ հետ չեմ վիճում այդ հարցում :) 19.02.2018
  • Դուք սխալ եք կարդում փաստաթղթերը և շփոթում եք Dispose(bool)-ը Dispose(-ի հետ): Dispose(bool)-ը առաջարկվող օրինաչափություն է վերջնական մշակիչն իրականացնելիս: Dispose()-ը IDisposable-ում սահմանված մեթոդն է: 20.02.2018

  • 2

    Երբ դուք օգտագործում եք օրինակ, որն իրականացնում է IDisposable ինտերֆեյսը, լավագույն պրակտիկան է այն օգտագործել որպես տեղական փոփոխական using հայտարարության մեջ:
    Այնուամենայնիվ, դա միշտ չէ, որ հնարավոր է:
    Որոշ դեպքերում դուք պետք է ներառեք դաշտ, որն իրականացնում է IDisposable ինտերֆեյս: Այս դեպքերում, դուք նույնպես պետք է դա իրականացնեք ինքներդ և օգտագործեք դրանք ձեր դասի Dispose(bool) մեթոդով:

    Օրինակ, Ենթադրենք, որ ցանկանում եք առաջադրանք պլանավորել: Բավականին հեշտ իրականացում է դասի օգտագործումը, որը պարունակում է System.Timers.Timer դաշտ, start, stop և doWork մեթոդ:
    Նման դեպքում դուք չեք կարող օգտագործել ժմչփը որպես տեղական փոփոխական, այն պետք է լինի դաշտ, և հետևաբար ձեր դասը պետք է իրականացնի IDisposable ինտերֆեյսը և ժամանակաչափը դնի իր Dispose(bool) մեթոդի վրա:

    Ահա պարզեցված կոդի օրինակ (կարծում եմ՝ մի փոքր չափազանց պարզեցված, բայց բավական լավ այս ցուցադրման համար)

    public abstract class Schedualer : IDisposable
    {
        private Timer _timer;
    
        public Schedualer(double interval)
        {
            _timer = new Timer(interval);
            _timer.Elapsed += _timer_Elapsed;
        }
    
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
    
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (_timer != null)
                {
                    _timer.Elapsed -= _timer_Elapsed;
                    _timer.Dispose();
                }
            }
        }
    
        protected abstract void OnTimerElapsed();
    
        protected void StartTimer()
        {
            _timer.Start();
        }
    
        protected void StopTimer()
        {
            _timer.Stop();
        }
    
        private void _timer_Elapsed(object sender, ElapsedEventArgs e)
        {
            _timer.Stop();
            try
            {
                TimerElapsed();
            }
            finally 
            {
                _timer.Start();
            }
        }
    }
    
    19.02.2018
  • @Moradof Բարելավել է այն՝ կանխելու Zombie վիճակ, որտեղ հավելվածը շարունակում է աշխատել, բայց ժամանակաչափը կանգ է առել: 07.11.2019
  • Նոր նյութեր

    Օգտագործելով Fetch Vs Axios.Js-ը՝ HTTP հարցումներ կատարելու համար
    JavaScript-ը կարող է ցանցային հարցումներ ուղարկել սերվեր և բեռնել նոր տեղեկատվություն, երբ դա անհրաժեշտ լինի: Օրինակ, մենք կարող ենք օգտագործել ցանցային հարցումը պատվեր ներկայացնելու,..

    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար
    Տիրապետել հանգստության արվեստին. մշակողի ուղեցույց՝ ճնշման տակ ծաղկելու համար Ինչպե՞ս հանգստացնել ձեր միտքը և աշխատեցնել ձեր պրոցեսորը: Ինչպես մնալ հանգիստ և զարգանալ ճնշման տակ...

    Մեքենայի ուսուցում բանկային և ֆինանսների ոլորտում
    Բարդ, խելացի անվտանգության համակարգերը և հաճախորդների սպասարկման պարզեցված ծառայությունները բիզնեսի հաջողության բանալին են: Ֆինանսական հաստատությունները, մասնավորապես, պետք է առաջ մնան կորի..

    Ես AI-ին հարցրի կյանքի իմաստը, այն ինչ ասում էր, ցնցող էր:
    Այն պահից ի վեր, երբ ես իմացա Արհեստական ​​ինտելեկտի մասին, ես հիացած էի այն բանով, թե ինչպես է այն կարողանում հասկանալ մարդկային նորմալ տեքստը, և այն կարող է առաջացնել իր սեփական արձագանքը դրա..

    Ինչպես սովորել կոդավորումը Python-ում վագրի պես:
    Սովորելու համար ծրագրավորման նոր լեզու ընտրելը բարդ է: Անկախ նրանից, թե դուք սկսնակ եք, թե առաջադեմ, դա օգնում է իմանալ, թե ինչ թեմաներ պետք է սովորել: Ծրագրավորման լեզվի հիմունքները, դրա..

    C++-ի օրական բիթ(ե) | Ամենաերկար պալինդրոմային ենթաշարը
    C++ #198-ի ամենօրյա բիթ(ե), Ընդհանուր հարցազրույցի խնդիր. Ամենաերկար պալինդրոմային ենթատող: Այսօր մենք կանդրադառնանք հարցազրույցի ընդհանուր խնդրին. Ամենաերկար palindromic substring...

    Kydavra ICAReducer՝ ձեր տվյալների ծավալայինությունը նվազեցնելու համար
    Ի՞նչ է ICAReducer-ը: ICAReducer-ն աշխատում է հետևյալ կերպ. այն նվազեցնում է նրանց միջև բարձր փոխկապակցված հատկանիշները մինչև մեկ սյունակ: Բավականին նման է PCAreducer-ին, չնայած այն..