क्या IAsyncEnumerable लौटने के तरीकों के लिए एक निश्चित नामकरण सम्मेलन है?


10

C # 5 के बाद अतुल्यकालिक प्रोग्रामिंग के लिए मॉडल asyncऔर awaitमॉडल प्रस्तुत किया गया , C # समुदाय एक नामजद सम्मेलन में एक "Async" प्रत्यय जोड़ने के लिए एक आवेगपूर्ण प्रकार को लौटाने के तरीकों पर आया, जैसे:

interface Foo
{
   Task BarAsync();
}

कई स्थिर कोड एनालाइज़र (रोसलिन-आधारित और गैर-रोसलिन-आधारित दोनों) तब से इस नामकरण सम्मेलन पर निर्भर करने के लिए लिखे गए हैं जब अतुल्यकालिक प्रोग्रामिंग के आसपास कोड गंध का पता लगाता है।

अब जब C # 8 ने अतुल्यकालिक एनुमेरबल्स की अवधारणा पेश की है, जो स्वयं प्रतीक्षा योग्य नहीं है, लेकिन इसके साथ संयोजन के रूप में उपयोग किया जा सकता है await foreach, नाम वापसी के तरीकों के लिए दो विकल्प प्रतीत होते हैं IAsyncEnumerable:

interface Foo
{
    // No "Async" suffix, indicating that the return value is not awaitable.
    IAsyncEnumerable<T> Bar<T>();
}

या

interface Foo
{
    // With "Async" suffix, indicating that the overall logic is asynchronous.
    IAsyncEnumerable<T> BarAsync<T>();
}

क्या उपरोक्त विकल्पों के संबंध में एक निश्चित नामकरण कन्वेंशन गाइडलाइन (C # भाषा टीम, .NET फाउंडेशन, या अन्य प्राधिकरणों से) है, जैसे कि C # 5 नामकरण कन्वेंशन को स्पष्ट रूप से मानकीकृत किया गया था और प्रोग्रामर के राय-आधारित निर्णय पर नहीं छोड़ा गया था?


2
विकल्प 2 यहीं सही लगता है, क्योंकि आपका यह कोड एसिंक्रोनस रूप से चलता है (मार्क मेथड asyncएंड इन await
यूज़

1
प्रश्न के बंद होने के जवाब में, मैंने यह प्रश्न करने के लिए संपादित किया है कि क्या एक निश्चित नामकरण सम्मेलन मौजूद है, और उदाहरण के लिए कि C # 5 में एक निश्चित नामकरण सम्मेलन कैसे स्थैतिक कोड विश्लेषण में विकास हुआ। इसलिए C # 8 का पालन करने से यह पैटर्न राय-आधारित कोडिंग वरीयताओं से परे औसत दर्जे के कोड गुणवत्ता में सुधार होगा।
hwaien

.NET कोर स्वयं Asyncवापसी के तरीकों के लिए प्रत्यय का उपयोग करता है IAsyncEnumerable, जैसे ChannelReader.ReadAllAsync । अन्य मामलों में, उदाहरण के लिए EF Core, AsAsyncEnumerable()का उपयोग किया जाता है जो पहले से ही स्पष्ट है
Panagiotis Kanavos

नामकरण दिशानिर्देश मनुष्यों के लिए कोड को समझना आसान बनाने के लिए मौजूद हैं। यदि कोड का उद्देश्य स्पष्ट नहीं है, तो प्रत्यय जोड़ें।
पनगीओटीस कानावोस

जवाबों:


1

.NET टीमें पहले से जो करती हैं, उससे बेहतर कोई दिशानिर्देश नहीं है:

  • ChannelReader.ReadAllAsync एक रिटर्न देता हैIAsyncEnumerable<T>
  • EF Core 3 में, परिणाम AsAsyncEnumerable ()IAsyncEnumerable कहकर लौटाए जाते हैं
  • System.Linq.Async, में ToAsyncEnumerable () IEnumerables, कार्य और में observables धर्मान्तरित IAsyncEnumerableरों
  • अन्य सभी ऑपरेटरों ने System.Linq.Asyncअपने नाम बनाए रखे। कोई है SelectAsyncया SelectAsAsyncEnumerable, बस Select

सभी मामलों में, यह स्पष्ट है कि विधि का परिणाम क्या है। सभी मामलों में, await foreachउपयोग किए जाने से पहले विधि के परिणामों की प्रतीक्षा की जानी चाहिए।

तो वास्तविक दिशानिर्देश वही रहता है - सुनिश्चित करें कि नाम व्यवहार को स्पष्ट करता है :

  • जब नाम पहले से ही स्पष्ट है, उदाहरण के लिए AsAsyncEnumerable()या इसके साथ ToAsyncEnumerable(), कोई प्रत्यय जोड़ने की आवश्यकता नहीं है।
  • अन्य मामलों में, Asyncप्रत्यय जोड़ें ताकि डेवलपर्स को पता हो कि उन्हें await foreachपरिणाम की आवश्यकता है ।

कोड एनालाइजर और जनरेटर वास्तव में तरीकों के नामों की परवाह नहीं करते हैं, वे कोड का निरीक्षण करके बदबू का पता लगाते हैं। एक कोड विश्लेषक आपको बता देंगे कि आप एक टास्क या इंतजार करना भूल गया await foreachएक IAsyncEnumerableकोई फर्क नहीं पड़ता कि कैसे आप तरीकों और चर कहते हैं। एक जनरेटर केवल प्रतिबिंब की जांच IAsyncEnumerableऔर उत्सर्जन के लिए उपयोग कर सकता हैawait foreach

यह स्टाइल एनालाइजर है जो नामों की जांच करता है। उनका काम यह सुनिश्चित करना है कि कोड एक सुसंगत शैली का उपयोग करता है ताकि डेवलपर्स कोड को समझ सकें । शैली विश्लेषक आपको बताएगा कि आपके द्वारा चुनी गई शैली का कोई विधि अनुसरण नहीं करती है। वह शैली टीम की या आमतौर पर स्वीकृत शैली गाइड हो सकती है।

और हां, हर कोई जानता है कि निजी उदाहरण क्षेत्रों के लिए सामान्य उपसर्ग है _:)


ChannelReader.ReadAllAsyncउदाहरण इंगित करने के लिए धन्यवाद । चूंकि यह सीधे .NET टीम से आता है, इसलिए इसका गलत तरीके से चलना मुश्किल है।
22

विश्लेषक पैकेज अक्सर शैली और गैर-शैली विश्लेषक के मिश्रण बैग के साथ आते हैं। उदाहरण के लिए, Microsoft.VisualStudio.Threading.Analyzers पैकेज में एक स्टाइल विश्लेषक है जो नामकरण सम्मेलन (VSTHRD200) और एक गैर-शैली विश्लेषक की जांच करता है जो खतरनाक स्थितियों का पता लगाता है जो संभावित रूप से गतिरोध (VSTHRD111) को जन्म दे सकता है। VSTHRD111 का लाभ लेने के लिए पैकेज का संदर्भ देने के लिए, एक परियोजना VSTHRD200 के साथ भी समाप्त हो जाएगी।
19 hwaien

2

यह एक async विधि नहीं है, इसलिए नाम 'Async' में समाप्त नहीं होना चाहिए। यह विधि प्रत्यय यह स्पष्ट करने के लिए एक सम्मेलन है कि विधि का इंतजार किया जाना चाहिए, या परिणाम टास्क के रूप में संभाला जाएगा।

मुझे लगता है कि एक सामान्य संग्रह-वापसी नाम उचित है। GetFoos (), या समान।


वे सभी प्रत्यय का उपयोग करने के लिए तर्क हैं Async। प्रत्यय का उपयोग .NET कोर में ही किया जाता है: ChannelReader.ReadAllAsync एक IAsyncEnumerable देता है। एक के IAsyncEnumerableसाथ प्रयोग किया जाना है await foreach, इसलिए प्रत्यय समझ में आता है।
पनगोटियोटिस कानावोस

1

एसिंक्स प्रत्यय और यहां तक ​​कि कीवर्ड asyncसिर्फ बॉयलरप्लेट है, यह कुछ पिछड़े हुए संगतता तर्क के अलावा अर्थहीन है। C # के पास उन कार्यों को अलग करने के लिए सभी जानकारी है जैसे कि यह उन yieldतरीकों में भिन्न है जो वापस आते हैं IEnumerable, जैसा कि आप जानते हैं कि आपको enumerableइस तरह के तरीकों पर कुछ भी या कुछ अन्य कीवर्ड जोड़ने की आवश्यकता नहीं है ।

आपको Async प्रत्यय जोड़ने की आवश्यकता है क्योंकि C # ओवरलोड के बारे में शिकायत करेगा, इसलिए अनिवार्य रूप से वे दोनों समान हैं और वे बहुरूपता के सभी नियमों द्वारा एक ही काम करते हैं (यदि हम खाते में मानवीय रूप से भ्रष्ट व्यवहार के कारक नहीं ले रहे हैं:

public interface IMyContract
{
    Task<int> Add(int a, int b);
    int Add(int a, int b);
}

लेकिन आप इसे इस तरह नहीं लिख सकते क्योंकि कंपाइलर शिकायत करेगा। लेकिन नमसते! यह इस एक राक्षसी को निगल जाएगा:

public interface IMyContract : IEnumerable<int>, IEnumerable<long>
{
}

और यहां तक ​​कि:

public interface IMyContractAsync
{
    Task<int> Add(int a, int b);
}

public interface IMyContract : IMyContractAsync
{
    int Add(int a, int b);
}

तो यही है। आप शिकायत करने के लिए कंपाइलर को रोकने के लिए Async जोड़ते हैं । चीजों को स्पष्ट करने के लिए नहीं। उन्हें बेहतर बनाने के लिए नहीं। यदि कोई शिकायत नहीं है - इसे जोड़ने का कोई कारण नहीं है, इसलिए आपके मामले में मैं इससे बचूंगा, जब तक कि यह नहीं हो जाता Task<IAsyncEnumerable>

पुनश्च: बस पूरी तस्वीर को बेहतर ढंग से समझने के लिए - अगर भविष्य में किसी को C # क्वांटम-कंप्यूटर विधि एक्सटेंशन (फंतासी, हुह) में जोड़ें, जो अलग-अलग प्रतिमानों में काम करेगा, तो हमें शायद एक और प्रत्यय की आवश्यकता होगी जैसे कि क्वांट या कुछ और, क्योंकि C # अन्यथा शिकायत करेंगे। यह ठीक उसी तरह का तरीका होगा लेकिन यह ऐसा करेगा कि यह दूसरे तरीके से काम करेगा। जैसे बहुरूपता करते हैं। जैसे इंटरफेस करते हैं।


1
क्षमा करें, लेकिन मुझे लगता है कि मैं असहमत हूं, यह वास्तव में एक ही काम करने के अलग-अलग दृष्टिकोण नहीं है - यह अधिक है - इसे अलग तरह से बुलाया जाने की उम्मीद है, और परिणाम को अलग तरीके से एकत्र किया जाना चाहिए। यह async और गैर- async के बीच सबसे अधिक अंतर है। मैं दृढ़ता से मानता हूं कि एसिंक्स को जोड़ना स्पष्टता के लिए है। मुझे लगता है कि यह भी Microsoft की सिफारिश है।
मादादोदेव

हाँ, मैं सहमत हूँ लेकिन असहमत हूँ। जैसे लिस्ट में आपके पास सिंपल सॉर्ट फंक्शन है न कि "क्विकॉर्ट", "रेडिक्सोर्ट", "बबलोर्ट", "मिक्सऑफसॉर्ट्स"। वे भिन्न हैं, गुंजाइश द्वारा उपयोग किए जाते हैं, लेकिन जाहिर तौर पर डिबगिंग उद्देश्यों के लिए इसके अलावा स्पष्टीकरण की आवश्यकता नहीं है (मेरा मतलब है कि आप केवल उनकी देखभाल करते हैं जब वे प्रदर्शन / संसाधनों पर प्रभाव डालते हैं)। इस मामले में DoThing और DoThingAsync किसी भी अन्य टेम्पर्ड एल्गोरिथ्म की तुलना में एक ही स्थिति में हैं, उन्हें स्पष्टीकरण की आवश्यकता नहीं है, यह या तो समर्थित है या नहीं, और केवल डीबगिंग के लिए उपयोगी है।
eocron

Thats अलग, async का मतलब है - हे कॉलर सुनिश्चित करें कि आप इसे सावधानी से संभालते हैं। टास्क को रिटायर करने का तथ्य यह कहने के लिए पर्याप्त नहीं है कि यह विधि वास्तव में Async है। कॉल करने वाले को गेटवेट ()। GetResilt () का उपयोग करने के लिए पता होना चाहिए। यह अलग नहीं है कि चीजें अंदर कैसे की जाती हैं।
मादादोदेव

यह पूरी तरह से कोड एनालाइजर और कंपाइलर का उद्देश्य है। IntellySense आसानी से आपके लिए यह इंगित कर सकता है, अतुल्यकालिक कोड में async एक पर सिंक विधि का उपयोग करके हाइलाइटिंग या यहां तक ​​कि गायब होने के लिए डेवलपर्स दिमाग का उपयोग करने की कोई आवश्यकता नहीं है। Async का उपयोग करते समय मेरे अनुभव से मुझे GetResult () का उपयोग करने की आवश्यकता है, लेकिन मुझे अक्सर Async के साथ पूरे कोड-बेस को प्रदूषित करने की आवश्यकता होती है।
eocron

जैसा कि किसी ने चिह्नित किया है कि - यह राय है। हम जो विश्वास करते हैं और खुश रहते हैं उस पर विश्वास रख सकते हैं :)
madoxdev
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.