Moje zwyczajowe podejście: Jeśli mam coś do napisania, co wydaje się być proste, to piszę to samodzielnie, bo wychodzę z zalożenia, że szukanie i uczenie sie biblioteki, która robi to za mnie, zajmie więcej czasu. Natomiast jeśli zadanie wydaje sie być na tyle trudne bądź skomplikowane, ze nie sądze, bym był w stanie zrobić je samodzielnie w rozsądnym czasie, a przy tym zadanie wydaje się byc na tyle generyczne, że ktoś musiał je juz rozwiązać, wtedy szukam biblioteki. (Np. do świętej pamięci mona (może jeszcze zmartwychwstanie...), kiedy musiałem narysować graf, wtedy poszukałem biblioteki do tego - także uzyłem zewnętrznej biblioteki do serializacji/deserializacji JSONa - ale to jedyne zewnętrzne biblioteki, jakich użyłem. A przepraszam, jeszcze użyłem 3-ciej biblioteki, do parsowania zakresów IP, bo zrobienie tego samodzielnie wymagałoby wczytania się w RFCy, więc ten wymóg w mojej świadomości usprawiedliwił użycie biblioteki).
Psioczenie, jakie czytam na tym forum od czasu do czasu, że devowie JS nie umieją samodzielnie wykonać najprostszych zadań i do każdej pierdoły korzystają z biblioteki, przez co z NPMa robi się smietnik, utwierdził mnie w przekonaniu, że postępuję słusznie.
Moje (skromne jeszcze) doświadczenie, z którego wynika, że szefowie zazwyczaj dążą do minimalizacji ilości zewnęntrznych zależności też mnie utwierdził w przekonaniu, że postepuję słusznie.
Na przykładzie: Aplikacja ASP.NET ma pisać logi do pliku. OK, pisanie do pliku, zadanie trywialne, zrobie to samodzielnie. Napisałem wraz z kolegą prościutką biblioteczkę do pisania logów, zarówno do pliku jak i do eventLoga. Używamy jej.
Ale teraz pojawiają się problemy. Serwer ASP.NET raczej nie powinien blokować. Więc pisanie do pliku powinno użyc WriteLineAsync
. Ale z drugiej strony nie wolno, by wiele wątków/procesów pisało do tego pliku wspóbieżnie. Rozwiązanie proste - lock
. Ups, ale połączenie tych dwóch wymogów już nie jest proste - nie wolno await
ować w lock
u.
public static class Log
{
public static string LogFile {get; internal set;}
public static string AppName {get; internal set;}
public static async Task Log(string message)
{
LogToEv(message);
await LogToFile(message);
}
private static async Task LogToFile(string message)
{
lock(LogFile)
{
using(var writer = new StreamWriter(LogFile, append: true)
{
await writer.WriteLineAsync($"[{DateTime.Now:g}]: [{AppName}]: {message}"); // Zakazane!
}
}
}
}
Pewnie da sie to prosto rozwiązać jakimiś mutexami, ale to musi być częsty problem - co mi szkodzi - zapytam się kogoś, jak to się robi, może być tak że tu jest jakiś "gotcha" w który wpadnę, jeśli spróbuję zrobić to samodzielnie w najprostszy sposób, jaki mi przychodzi do głowy.
Pytam sie na C# Discordzie. Dyskusja przebiega mniej więcej tak:
Ja: pytam sie o powyższe
Odpowiedź: Czemu nie używasz biblioteki, takiej tak Serilog, która to robi?
Ja: Przecież pisanie do pliku to trywialne zadanie, czy potrzebuję do tego bibliotki?
Odpowiedź: Ty nie chcesz tylko pisać do pliku, ty chcesz robić to w sposób nieblokujący, a Serilog to robi i rozwiązuje problemy, na które teraz wpadasz.
Ja: Zaraz, chyba jestem głupi. Tu w ogóle nie potrzebny jest async
. Async słuzy do tego, by nie blokować, by umożliwić jednoczesne przetwarzanie requestu przez wiele procesów. Ale przecież dokładnie tego musimy zakazać, gdy piszemy do pliku. Rozwiazanie proste - tutaj blokowanie jest konieczne, zostawić lock
, wyrzucić async
.
Odpowiedź: Czemu nie uzywasz biblioteki, takiej jak Serilog, która to robi i rozwiązuje problemy, na które teraz wpadasz?
Ech. W ten sposób niewiele się nauczyłem.
Oprócz jednego. Czy moje podejście unikania używania dziesięciu zewnętrznych bibliotek do zadań, które wydają się być proste, rzeczywiście jest słuszne? Może powinienem jednak przeprosić sie z długą listą zewnętrznych zależnosci i poświęcic czas na czytanie dokumentacji wszystkich tych bibliotek? (Zamiast przeznaczyć czas na poznanie mniejszej ilości narzędzi, za to bardziej dogłebnie, czyli w szczególności dobrze poznać C#?)
Albo właśnie przeciwnie, ta "dyskusja" udowodniła słusznośc mojego podejścia? Po prostu ludzie, którzy nic nie umieli powiedzieć ponad "użyj Seriloga" to sa owi programiści, którzy samodzielnie nie potrafią wykonać najprostszych zadań i dlatego do każdego kiwnięcia lewym palcem u prawej nogi potrzebuja zewnętrznej biblioteki? Nic nie mogli powiedzieć, bo nic nie wiedzą, w szczególności pojęcia nie mają, jak w C# działa async
?
kmphkmphasync
, ale słuzący do tego, by faktyczne zapisanie do pliku odbyło sie po zwróceniu odpowiedzi na request, a nie przed. I znowu albo/albo: Interpretacja (a): To są właśnie owe subtelności, do których trzeba zatrudnić zewnętrzną bibliotekę, bo jak widać pozornie trywialne zadanie jednak nie jest trywialne = wynajdowanie koła na nowo; albo (b) to jest proste o ile zna się język C# a żeby być programista C# to trzeba znać C#...kmphSemaphoreSlim
.