Węzeł.js vs Async / in.net

Czy ktoś może mi wyjaśnić / przekierować, jaka jest różnica między węzłem.model asynchroniczny js (non blocking thread) vs każdy inny język, na przykład asynchroniczny sposób obsługi We/Wy w c#. wygląda to dla mnie, że oba są tym samym modelem. Uprzejmie sugeruję.

Author: PKV, 2014-01-24

4 answers

Oba modele są bardzo podobne. Istnieją dwie podstawowe różnice, z których jedna odchodzi wkrótce (dla pewnej definicji "wkrótce").

Jedną różnicą jest ten węzeł.js jest asynchronicznie jednowątkowy, natomiast ASP.NET jest asynchronicznie wielowątkowy. Oznacza to węzeł.kod js może wprowadzać pewne uproszczone założenia, ponieważ wszystkie Twój kod zawsze działa na tym samym, dokładnym wątku. Więc kiedy twój ASP.NET kod await s, może być wznowiony na innym wątku, a do ciebie należy unikanie takich rzeczy jak thread-local state.

Jednak ta sama różnica jest również siłą dla ASP.NET, ponieważ oznacza async ASP.NET może skalować się po wyjęciu z pudełka do pełnych możliwości sever. Jeśli weźmiemy pod uwagę, powiedzmy, maszynę 8-rdzeniową, to ASP.NET może przetwarzać (synchroniczne części) 8 żądań jednocześnie. Jeśli umieścisz węzeł.js na rozbudowanym serwerze, wtedy często jest uruchamiane 8 oddzielnych instancji Node.js i dodać coś takiego jak nginx lub prosty Niestandardowy load balancer obsługujący żądania routingu dla tego serwera. Oznacza to również, że jeśli chcesz, aby inne zasoby były współdzielone na całym serwerze (np. pamięć podręczna), musisz je również przenieść poza proc.

Druga istotna różnica to różnica w języku, a nie w platformie. Asynchroniczna obsługa JavaScript jest ograniczona do wywołań zwrotnych i obietnic, a nawet jeśli używasz najlepszych bibliotek, nadal będziesz miał naprawdę niezręczny kod, gdy zrobisz coś nietrywialnego. In contrast, na async/await wsparcie w C# / VB pozwala na pisanie bardzo naturalnego kodu asynchronicznego (a co ważniejsze, , który można utrzymać).

Jednak różnica językowa odchodzi. Kolejna wersja JavaScript wprowadzi generatory, które (wraz z biblioteką pomocniczą) będą tworzyć kod asynchroniczny w węźle.js tak samo naturalne jak dzisiaj przy użyciu async/await. Jeśli chcecie zagrać z "coming soon" teraz, Generatory zostały dodane W V8 3.19, który został zwinięty do węzła.js 0.11.2 (Unstable branch). Przekazać --harmony lub --harmony-generators, aby jawnie włączyć obsługę generatora.

 68
Author: Stephen Cleary,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 19:02:26

Różnica między węzłem.model asynchroniczny js i model async/wait C # jest ogromny. Model asynchroniczny, który ma węzeł.js jest podobny do starego modelu asynchronicznego w C# i. Net o nazwie Event-based Asynchronous Pattern (EAP). C# i. Net mają 3 modele asynchroniczne, można o nich przeczytać w asynchroniczne wzorce programowania . Najbardziej nowoczesny model asynchroniczny w C# jest oparty na zadaniach z C# ' s async i wait słowa kluczowe, możesz przeczytać o tym na Task-based Wzorzec Asynchroniczny . The C # 's async/wait {[2] } słowa kluczowe sprawiają, że asynchroniczny kod jest liniowy i pozwala uniknąć" Callback Hell " znacznie lepiej niż w jakimkolwiek innym języku programowania. Musisz po prostu spróbować, a potem nigdy nie zrobisz tego w inny sposób. Po prostu piszesz kod zużywający operacje asynchroniczne i nie martw się o czytelność, ponieważ wygląda na to, że piszesz jakikolwiek inny kod. Zapraszam do obejrzenia tego Filmu:

  1. programowanie asynchroniczne nurkowanie
  2. asynchroniczny w ASP.NET
  3. zrozumienie asynchronicznych i oczekiwanych Zadań

I proszę, spróbuj zrobić coś asynchronicznego zarówno w C# , jak i Node.js do porównania. Zobaczysz różnicę.

EDIT : Od Węzła.js V8 JavaScript engine obsługuje Generatory, zdefiniowane w ECMAScript 6 Draft ," Callback Hell " w kodzie JavaScript również można łatwo uniknąć. wprowadza jakąś formę asynchronizacji / oczekiwania do życia w JavaScript

 14
Author: Ashot Muradian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-06-01 11:49:55

W nodejs wszystkie żądania trafiają do kolejki zdarzeń. Pętla zdarzeń węzła używa pojedynczego wątku do przetwarzania elementów w kolejce zdarzeń, wykonywania wszystkich prac nie-IO i wysyłania do C++ threadpool (przy użyciu wywołań zwrotnych javascript do zarządzania asynchronią) wszystkich prac związanych z IO. Wątki C++ następnie dodają do kolejki zdarzeń jej wyniki.

Różnice z ASP.NET (dwa pierwsze dotyczą praktycznie wszystkich serwerów internetowych, które pozwalają na asynchroniczne IO) jest to, że:

  1. ASP.NET używa innego wątku dla każdego przychodzące żądania , więc masz narzut przełączania kontekstu
  2. Nie jest tak idiomatyczne jak nodejs, gdzie wywołania interfejsu API związane z IO są de facto asynchroniczne (z wywołaniami zwrotnymi).]} W przeciwieństwie do nodejs, w czasie kompilacji można dodawać "callbacks", dzięki czemu można pisać kod liniowy (bez przechodzenia funkcji callback). NET' "wait-async" add jest krokiem w czasie kompilacji, aby dodać "callbacks", dzięki czemu można pisać kod liniowy (bez przechodzenia funkcji callback), w przeciwieństwie do nodejs

Jest tyle miejsc w sieci, które opisują architekturę węzła, ale oto coś : http://johanndutoit.net/presentations/2013/02/gdg-capetown-nodejs-workshop-23-feb-2013/index.html#1

 6
Author: billy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-24 16:17:22

Różnica między asynchronizacją w Nodejs i. NET polega na używaniu prewencyjnej wielozadaniowości dla kodu użytkownika. . NET używa prewencyjnej wielozadaniowości dla kodu użytkownika, a Nodejs nie.

Nodejs używa wewnętrznej puli wątków do obsługi żądań IO oraz pojedynczego wątku do wykonywania kodu JS, w tym wywołań zwrotnych IO.

Jedną z konsekwencji używania preemptive multitasking (. NET) jest to, że współdzielony stan może być zmieniany przez inny stos wykonania podczas wykonywania stosu. To jest nie tak jest w Nodejs - żadne wywołanie zwrotne z operacji asynchronicznej nie może być uruchomione jednocześnie z aktualnie wykonywanym stosem. Kolejne stosy wykonywania po prostu nie istnieją w Javascript. Wynik operacji asynchronicznej będzie dostępny dla wywołań zwrotnych tylko wtedy, gdy bieżący stos egzekucji całkowicie. Mając to, simple while(true); zawiesza Nodejs, ponieważ w tym przypadku bieżący stos nie kończy się i następna pętla nigdy nie jest inicjowana.

Aby zrozumieć różnicę rozważ dwa przykłady, jeden dla js jeden dla net. var p = new Promise(function (resolve) { setTimeout( resolve, 500, " Moja zawartość"); }); p. then (function (value) { / / ... wartość = = = "moja treść"

W tym kodzie możesz bezpiecznie umieścić funkcję obsługi (then) po "uruchomieniu" operacji asynchronicznej, ponieważ możesz być pewien, że żaden kod wywołania zwrotnego zainicjowany przez operację asynchroniczną nigdy nie zostanie wykonany, dopóki cały bieżący stos wywołań nie zakończy się. Wywołania zwrotne są obsługiwane w kolejnych cyklach. Jeśli chodzi o wywołania timera, są to traktowałem to samo. Async timer event justs umieszcza przetwarzanie wywołania zwrotnego w kolejce do przetworzenia w następnym cyklu.

W. NET jest inaczej. Nie ma cykli. Istnieje uprzedzająca wielozadaniowość.
ThreadPool.QueueUserWorkItem((o)=>{eventSource.Fire();});
eventSource.Fired += ()=>{
 // the following line might never execute, because a parallel execution stack in a thread pool could have already been finished by the time the callback added.
 Console.WriteLine("1");
}

Oto Kod Hello World. Net a-la Nodejs do zademonstrowania przetwarzania asynchronicznego na pojedynczym wątku i korzystania z puli wątków dla asynchronicznego IO, tak jak robi to node. (. Net zawiera wersje TPL i IAsyncResult operacji async IO, ale nie ma różnicy w tym celu przykład. W każdym razie wszystko kończy się różnymi wątkami na puli wątków.)

void Main()
{
    // Initializing the test
    var filePath = Path.GetTempFileName();
    var filePath2 = Path.GetTempFileName();
    File.WriteAllText(filePath, "World");
    File.WriteAllText(filePath2, "Antipodes");

    // Simulate nodejs
    var loop = new Loop();

    // Initial method code, similar to server.js in Nodejs. 
    var fs = new FileSystem();

    fs.ReadTextFile(loop, filePath, contents=>{
        fs.WriteTextFile(loop, filePath, string.Format("Hello, {0}!", contents),
            ()=>fs.ReadTextFile(loop,filePath,Console.WriteLine));
    });

    fs.ReadTextFile(loop, filePath2, contents=>{
        fs.WriteTextFile(loop, filePath2, string.Format("Hello, {0}!", contents),
            ()=>fs.ReadTextFile(loop,filePath2,Console.WriteLine));
    });

    // The first javascript-ish cycle have finished.

    // End of a-la nodejs code, but execution have just started.

    // First IO operations could have finished already, but not processed by callbacks yet

    // Process callbacks
    loop.Process();

    // Cleanup test
    File.Delete(filePath);
    File.Delete(filePath2);
}

public class FileSystem
{
    public void ReadTextFile(Loop loop, string fileName, Action<string> callback)
    {
        loop.RegisterOperation();
        // simulate async operation with a blocking call on another thread for demo purposes only.
        ThreadPool.QueueUserWorkItem(o=>{
            Thread.Sleep(new Random().Next(1,100)); // simulate long read time

            var contents = File.ReadAllText(fileName);
            loop.MakeCallback(()=>{callback(contents);});
        });
    }

    public void WriteTextFile(Loop loop, string fileName, string contents, Action callback)
    {
        loop.RegisterOperation();
        // simulate async operation with a blocking call on another thread for demo purposes only.
        ThreadPool.QueueUserWorkItem(o=>{
            Thread.Sleep(new Random().Next(1,100)); // simulate long write time

            File.WriteAllText(fileName, contents);
            loop.MakeCallback(()=>{callback();});
        });
    }
}

public class Loop
{
    public void RegisterOperation()
    {
        Interlocked.Increment(ref Count);
    }
    public void MakeCallback(Action clientAction)
    {
        lock(sync)
        {
            ActionQueue.Enqueue(()=>{clientAction(); Interlocked.Decrement(ref Count);});
        }
    }

    public void Process()
    {
        while(Count > 0)
        {
            Action action = null;
            lock(sync)
            {
                if(ActionQueue.Count > 0)
                {
                    action = ActionQueue.Dequeue();
                }
            }

            if( action!= null )
            {
                action();
            }
            else
            {
                Thread.Sleep(10); // simple way to relax a little bit.
            }
        }
    }

    private object sync = new object();

    private Int32 Count;

    private Queue<Action> ActionQueue = new Queue<Action>();
}
 2
Author: George Polevoy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-09-09 07:32:13