Ich möchte gerne mehrere unabhängige Grpc Services auf einem Host laufen lassen.
Kann ich das mit dem Grpc.AspNetCore Template machen oder eher nicht? Mir sind die Vorteile durch Grpc.AspNetCore gegenüber einem Console-Programm bisher nicht so ganz klar. Gibt es da eine Übersicht?
Würde mir an Deiner Stelle eher mar pp anschauen, um aus dem Perl Skript eine exe zu machen, die Du dann aufrufen kannst. Ist aber schon lange her, seit ich so etwas mal gemacht habe.
Ich würde mir auch R.NET anschauen - Skripte aufrufen würde bedeuten, daß Du keine Daten austauschen kannst.
Ich würde mir an Deiner Stelle mal Fidler ansehen - es gibt da auch Extensions, die automatisch den C# Code zum Recording aufzeichnen, um schnell ein Codegerüst zu bekommen.
Mit der VS Version hat das nix zu tun.
Du musst Dir per Nuget Google Protobuf installieren.
Alternativ kannst Du Protobuf-Net ein Tool zum Generieren der Klassen finden.
Gibt doch ein paar freie Alternativen.
Die würde ich an Deiner Stelle benutzen. Ich würde aber die Bibliothek gut nach außen abkapseln, so daß man im Zweifel leicht die Bibliothek wechseln kann, wenn sich da etwas ändert.
An Deiner Stelle würde ich etwas wie SignalR oder gRPC anstatt Sockets nehmen.
Wenn Du den Socket nimmst, dann musst vor allem entweder im Protokoll am Anfang die Länge mitteilen oder mit einem Trennzeichen arbeiten.
Du musst dann auf jeden Fall mehrfaches Lesen vom Socket implementieren, wenn Deine Nachrichten länger als die BufferSize sind.
Im VS brauchst Du zwei Projekte.
Ein Class Library Projekt, in dem Du die Proto Datei hast. Mit der neuen Version der Tools musst Du die Proto Datei nur als Element in VS hinzufügen ("Add existiting item) - dann gRPC, gRPC Tools und Protobuf Nuget Paket hinzufügen und kompilieren.
Das zweite Projekt ist dann eine Consolen-Anwendung, die das Class Library Projekt referenziert und die gRPC und Protobuf Nuget Pakete referenziert. Du startest dann dort wie im Beispiel den Server.
In der Server Implementierung erbst Du von der Class Library die Server Implementierung und überschreibst die Methoden für die Funktionsaufrufe.
Die Beispiele sind sehr gut. Die Proto Dateien kann mit VSCode mit einem Plugin für Syntax-Highlighting erstellen.
Ich implementiere nur das Aufrufen des Proto Compilers als Pre-Build Event in Visual Studio, so daß der Build ohne Command Line auskommt:
cd $(ProjectDir)
$(SolutionDir)packages\Grpc.Tools.1.18.0\tools\windows_x86\protoc.exe xxx.proto --csharp_out=$(ProjectDir) --grpc_out=$(ProjectDir) --plugin=protoc-gen-grpc=$(SolutionDir)packages\Grpc.Tools.1.18.0\tools\windows_x64\grpc_csharp_plugin.exe
Wenn es sich bei den beiden dlls um Assemblies handelt, dann könntest Du die mit ILMerge zusammenfassen.
Wenn die DLLs nativer Code sind, dann wüßte ich nicht, wie Du die Dlls statisch zusammenfügen kannst.
Selbst das Verdoppeln hat nicht geholfen - bin etwas ratlos.
Habe gesehen, daß Gamer Azure zum Spielen nutzen und das würde ich mit meinen Anforderungen vergleichen.
Ich versuche gerade eine 3rd Party App von einem lokalen PC auf Azure zu heben.
Zurzeit läuft die App auf einem Xeon 2630.
Obwohl ich schon F4 als Größe gewählt habe, gehen mir die CPU - Ressourcen aus. Ich vermute mal, daß es am fehlenden Turbo Boost liegt. Was würdet ihr mir für eine Maschinengröße empfehlen?
Direkt ist das nicht so einfach nicht möglich.
Es gibt aber das Nuget Paket System.Linq.Dynamic.Core, mit dem Du das machen kannst.
Probiere mal, ob Dir ein serialPort1.Flush() nach dem WriteLine() hilft.
Für solche Aufgaben solltest Du benchmarkdotnet nehmen.
StopWatch ist auch nicht sauber für das Messen von Microbenchmarks.
Würde an Deiner Stelle eher C# 7.0 in a Nutshell kaufen und mir dann das Kapitel über Networking anschauen, wenn Du neu anfängst.
Aktuell ändert sich gerade viel, da mit Dotnet Core und Pipelines neue Möglichkeiten kommen, die wirklich kniffligen Probleme wie BackPressure für Sockets im Framework abzuarbeiten.
Andere Möglichkeit wäre SimplSockets zu benutzen oder als Beispiel zu nehmen.
Habe das problematische Assembly nach dotnetstandard 2.0 migriert und da ist das Problem verschwunden.
Bei Kopieren des Codes in ein neues Projekt und beim Aufräumen von alten Versionsdateien habe ich gemerkt, dass die Bibliothek schon 8 Jahre alt ist 😉
Unverwalteter Speicher ist Speicher, der nicht mit dem Garbage Collector überwacht wird.
Den bekommst Du entweder mit GCHandle.Alloc oder wenn Du mittels P/Invoke externen Code ausführst und Du dann einen Zeiger auf einen Speicherbereich bekommst.
Mit COREHOST_TRACE 1 sieht man etwas mehr - aber so richtig schlau hat mich das auch nicht gemacht.
Fusion Log gibt es nicht für Dotnet Core.
Ich hatte halt gehofft, dass ich ohne große Code-Änderungen auskomme.
Bei einer einzelnen Projekt-Abhängigkeit hatte ich kein Problem auch mit log4net gehabt.
Ich werde erstmal alles zu netstandard2 umändern und dann gegebenfalls auf Serilog wechseln.
Muss mir ohnehin noch anschauen, wie ETW mit DotNet Core funktioniert oder nicht.
Ich habe bei der Migration nach DotNet Core Probleme mit Type Initalization Exception/Method not Found mit log4Net - obwohl alle Äbhängigkeiten die letzte Version von log4Net benutzen.
Ich habe auch im Projekt in csproj
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
gesetzt - gibts noch etwas anderes, was ich vergessen haben könnte.
Danke für den Hinweis "Publish". Damit komme ich in der Tat weiter.
Mich hatte vor allem irritiert, daß ich einen Teil der dlls gesehen hatte.
In meiner produktiv Umgebung arbeite ich hinter einer Firewall, die keine Verbindungen zu nuget möglich macht.
Wenn ich nun in VS 2017 ein Dotnet Core Projekt baue, dann fehlen mir unter \bin\Release\netcoreapp2.1 viele MS dlls. Wie bekomme ich die nun alle in ein Verzeichnis, so dass ich via eines einzigen Archivs meine Applikation installieren kann?
Wie bekommt man denn am besten seine Nuget packages hinter die Firewall.
Das ganze .nuget/packages von der Entwicklermaschine kopieren wäre nicht sehr elegant.
Man muss tatsächlich
"C:\Program Files (x86)\dotnet\dotnet.exe" aufrufen - dann klappts....
Ich bin gerade dabei mein erstes Dotnet Core Projekt fertigzustellen.
Da ich einen 32 bit DLL referenziere, muss ich die 32 Bit Runtime benutzen.
Wenn ich nun in den Projekt-Properties 32 Bit als Target angebe, dann bekomme ich bei dotnet run den Fehler
Es wurde kein ausführbares Projekt gefunden. .
Ich habe auch versucht ebenfalls das x86 sdk zu installieren, aber das hat leider nix gebracht. Habt Ihr sonst noch Tipps?
Quartz sehe ich relativ unkritisch, da das meiste alles beim Warmup passiert.
Wenn Du halbwegs deterministisch sein willst, dann solltest Du Dich vor allem beim Code zum Extrahieren der Daten und beim anschließenden Serialisieren anstrengen, effizient zu sein.
Da Du Dotnet Core 2.1 benutzt, solltest Du vor allem mit Span<T> arbeiten, damit Du nicht zu viele Arrays allozierst.
In jedem Fall würde ich Dir vor allem raten, daß Du mit BenchmarkDotnet für Performance Tests arbeitest und mit Perfview das Verhalten Deiner Applikation misst - insbesondere um das Verhalten das Garbage Collectors einschliesslich der Pausen nachvollziehen zu können.
In einer async Methode macht Task.Run keinen Sinn - Du bist ja schon der Stelle asynchron in einem eigenen Task, den hier die Textbox erstellt hat.
Ich persönlich benutze EPPlus für so etwas.
Man kann auch direkt das Office XML benutzen.
Bei 200.000 Spalten wirst Du vielleicht recht viel Speicher brauchen - aber das sollte sehr schnell sein.
Der Garbage Collector arbeitet nicht-deterministisch neben Deinem Applikations-Code als Teil der Runtime. Da spielt es keine Rolle, ob Du Schleifen oder LINQ benutzt, auch wenn LINQ mehr Arbeit für den Garbage Collector macht.
Wenn Du Dich richtig reingraben willst, dann musst Du mit Perfview einen Dump beim Crash erzeugen und dann mit dem WinDbg Debugger ran. Am besten dann mehrere davon und dann kannst Du Glück haben, was zu sehen.
Ich bin neben Span/Slice noch in Richtung Utf8Parser und auch noch MemoryMarshal.Cast am testen, da ich UTF8 String verarbeite.
Wird Zeit, daß ich mal End2End mit BenchmarkDotNet schaue, was am schnellsten ist. Bin mir da nicht so sicher.
Die Reproduktion von solchen Sachen ist Glücksache, da solche Fehler meistens passieren, wenn der Garbage Collector Objekte verschiebt, weil er den Speicher kompakter machen will. Der Garbage Collector ist dabei nicht deterministisch.
Du brauchst übrigens nicht zwangsweise unsafe Code - z.B. ein zu langes Buffer.BlockCopy kann auch da hinführen.
Mein Code wird nur von uns selber benutzt.
Migrieren möchte ich vor allem aus Performance Gründen - Span statt Substring ist in den kritischen performance-kritischen Bereichen bereits implementiert. Ich bin sehr gespannt, wie viel das bringen wird, da ich teilweise schon mehrere 100 ms Pausen bei der Garbage Collection in Gen 0 und 1 sehe.
Ich tendiere bisher zu neuen Projekten - ich habe zum Beispiel bisher VS Batches zum Build benutzt und da hat das erste Projekt nach Wechsel zu Multitarget gleich VS regelmässig zum Absturz gebracht. Bei den neuen Projekten verliert man zwar die Historie für jede Datei, aber man beginnt auch ohne Altlasten.
Two-way wäre streaming von Client und Server - das habe ich bisher noch nicht gemacht, da ich das bisher nicht gebraucht habe. Ich streame rein vom Server her
Der Server wird in jedem Fall rein mit Async Methoden implementiert - dafür benutze ich den BufferBlock aus TPL Dataflow - da die BlockingCollection kein Methode mit await anbietet.
Ich benutze schon recht lange gRPC.
Funktioniert sehr stabil - benutze es mittlerweile auch mit Python zusammen für eine externe statistische Bibliothek.
Ist wirklich narrensicher meiner Meinung nach und sehr performant.
Finde es schön, dass die API synchron und asynchron anbietet - so das man beides je nach Anwendungsfall mischen kann.
Was meinst Du mit Callbacks - das gRPC API bietet async Methoden, wo Du mit await arbeiten kannst und streaming, so dass zu einem Request mehrere Antworten kommen können.
Ich bin gerade auch bei der .NET Core Migration von bestimmten Komponenten, aber da wird es noch 1-2 Monate dauern, bis ich dort produktive Erfahrungen gemacht habe.
Wie würdet Ihr bestehende Visual Studio 2017 Projekte nach dotnetcore migrieren?
Mit der Portabilitätsanalyse habe ich gesehen, daß es auf Code Ebene außer der Änderung im Konfigurationsmodell keine Probleme gibt, was recht schnell und sicher zu Ändern ist. Meine Projekte sind bisher Windows Desktopm Console App.
Ich hatte es mit Multitarget probiert, doch das hat die Projekte in Visual Studio zum Absturz gebracht - wahrscheinlich, weil ich bisher mit Batch für den Build arbeite. Wahrscheinlich müsste ich das dann alles rausnehmen, damit das funktioniert.
Wie sind Eure Erfahrungen/Empfehlungen?
Ich benutze für Socks5 Privoxy als Proxy.
Ich kann Menten's Problem schon verstehen, bei WPF/Winforms gibt es sehr viele verschiedene Wege, wie man Datenbank-Oberflächen programmieren kann.
Da muss man selber den eigenen Weg finden, was am Anfang einiges an Zeit kostet und eine gesunde Mischung zwischen reiner Lehre und praktischem Aufwand sein soll. Dazu sollte man sich mit Dingen wie Fody und einem MVVM Framework wie ReactiveUI oder MVVM Light beschäftigen, damit man möglichst wenig Arbeit hat. Da findet man auch die besten Beispiele zum Nachbauen.
Würde an Deiner Stelle falls es erlaubt ist die API von Google nehmen.
Normalerweise hat man Lesen in einem eigenen langlaufendem Task.
Das Blockieren spielt da keine große Rolle und nimmt kaum Ressourcen.
Wenn Du mit vielen Daten arbeitest, bekommst Du sogar Probleme, wenn Du nicht schnell genug abnimmst (Stichwort TCP Requeue).
Hallo,
Ich habe ein paar Fragen zu Azure.
Kann ich in Azure auf eine virtuelle Maschine eine DLL installieren, die Zugriff auf die Registry benötigt ?
Kann ich in Azure einen Open VPN Client installieren? Dafür benötige ich ein TARP Netzwerk-Treiber installieren?
Wo stellt man sonst solche Azure Fragen?
In Github findest Du für alle Releases die ReleaseNotes, KnownIssues und API Changes. Da solltest Du fündig werden.
Wenn es um reines Request/Response Handling geht, dann kann man sehr einfaches und elegantes mit dem ActionBlock machen.
private void OnMessage(Response response)
{
lock (locker)
{
try
{
Cache[response.PrivateKey].Post(response);
Cache[response.PrivateKey].Complete();
Cache.Remove(response.PrivateKey);
}
catch (Exception ex)
{
Log.Error("Error in message handling:" + ex);
}
}
}
public async Task<Response> Send(Request request)
{
Response result = null;
var actionBlock = new ActionBlock<Response>(message => result = message);
lock (locker)
{
var key = PrivateCounter++.ToString();
request.SetPrivate(key);
Cache.Add(key, actionBlock);
device.Send(request);
}
await actionBlock.Completion;
return result;
}
Vielleicht noch etwas grundsätzliches - Lesen vom Drucksensor solltest Du immer in einem eigenen Thread, der dann in einen Buffer schreibt. Ich benutze für den Buffer meist den Disruptor.
.NET erlaubt schon hohen Durchsatz, wenn man vor allem mit wiederverwerteten Objekten arbeitet, so daß man GC 2 umgeht. Das erfordert aber eine aufwändigere Programmierung und ist unmöglich, wenn Du gleichzeitig Server und Clientaufgaben in einem WPF Programm mischst.
Ein mehrdimensionales Array musst Du natürlich mit
byte [, ,]
definieren. Dein Beispiel benutzt
byte[][,]
Das ist nicht das Gleiche.
Du unterstellst, dass der Konstruktor mit Parameter genauso funktioniert, wie parameterloser Konstruktor und dann Setzen der Parameters. Das kann das Gleiche sein, es kann es aber auch nicht sein. Gerade bei Multi-Threading sollte man solche Annahmen tunlichst unterlassen.
Schau Dir mal die Stackoverflow Architektur an. Das gibt Dir einen Einblick, wie so eine Architektur richtig aufgebaut ist. Facebook selber wird mit noch viel mehr Servern arbeiten.
Ich würde an Deiner Stelle mal gRPC, ZeroMQ, Aeron oder eine andere Middleware ausprobieren - das macht man, wenn man kein Google oder Facebook ist.
@T-Virus
Du hast natürlich recht.
Ich bin gerade ein gebranntes Kind, was async/Tasks anbetrifft. Habe festgestellt, daß 50 Mio. mal async aufrufen zu einer Heap Fragmentation führt,. Dann braucht auf einmal eine Gen 1 GC Collection mehrere Sekunden. Nur leider bietet die Datenbank kein anderes API. Also muss man lieber mit 2 Prozessen arbeiten. Wenn man so etwas sieht, dann wird man wieder demütig, was Performance anbetrifft.
Du solltest Dir mehr Sorgen machen, warum Du den Thread nicht schon beim Starten des Programmes erzeugst.
Der Overhead für das Starten eines Threads wird viel größer sein als der für das Setzen des Namens. Darum wurde der Task Pool geschaffen,
Wenn Du eine performante Applikation schreiben willst, dann geht es vor allem darum, den Garbage Collector möglichst nie in Generation 2 zu benötigen. Dafür musst Du vor dem eigentlichen Event Loop schon alles gestartet und initialisiert haben, was nur geht und Objekte und Threads wiederverwenden statt neu zu erzeugen.