Ohne bislang einen Blick auf das Projekt geworfen zu haben:
Bist du dir sicher, dass du hier nicht Business- und Data-Layer vermischst? Deine Erläuterung riecht danach.
Diese EF-POCO Klassen sind einfache Datentransporteure ohne Gebimmel und Gebammel, denn dieses gehört in den Business-Layer und dessen Klassen.
Zeig doch mal ein wenig Code ...
Wo ist denn die Klasse ValidationResults
definiert?
Ich tippe auf einen schnöden Schreibfehler und es muss überall von ValidationResults
nach ValidationResult
geändert werden.
😉
@Th69
Ein array implementiert auch IList 😉
Ganz schön spitz heute morgen 😉.){gray}
Finde ich nicht.
Die Summe entspricht in den meisten Unternehmen der Leasingrate von 2 Monaten für den Firmenwagen des Geschäftsführers. Wenn die Kosten auf Teufel komm raus wieder reingeholt werden müssen, dann kann der ja beim nächsten Wechsel des Fahrzeugs 2 Monate mit einem günstigen Bestandsfahrzeug vorlieb nehmen.
Ich kenne Unternehmer, die das ohne mit der Wimper zu zucken machen würden. Brauchen die aber gar nicht, weil die auch gut im Rechnen sind.
Meiner Meinung nach hat ein Unternehmen (in der Größe), dass bei €1641,00 netto (3 Lizenzen VS2017 Pro, Microsoft Store) einmaliger Investition überlegen muss, weitaus größere Probleme.
Werden die Gehälter pünktlich bezahlt?
Übrigens: Eine Investition ist eine Ausgabe, die sich nach Zeitraum X amortisiert hat.
Das kann ich so nicht sagen, aber man muss auch ausschließen, dass wir nicht Birnen und Äpfel vergleichen.
.net 4.7 aktualisiert auch .net 4.5.x und .net 4.6.x
Mit welchem VS arbeitest du und welches .net FW ist für die Anwendung festgelegt?
Welche .net FW hast du installiert?
Hier, mit .net 4.7 installiert, kann ich das nicht nachvollziehen
@123thomas
Wenn du den Thread, von dem dieser hier abgetrennt wurde, berücksichtigst, dann geht es hier um eine JSON Serialisierung 😉
using System;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var data = new object[] {
new object[] { "State", "Count" },
new object[] { "annulliert", 12 },
new object[] { "Gebaut", 25 },
new object[] { "Eingang", 65 },
new object[] { "Ausgang", 22 },
new object[] { "Geliefert", 5 },
};
var dataJson = JsonConvert.SerializeObject(data,Formatting.Indented);
Console.WriteLine(dataJson);
}
}
Ausgabe:
[
[
"State",
"Count"
],
[
"annulliert",
12
],
[
"Gebaut",
25
],
[
"Eingang",
65
],
[
"Ausgang",
22
],
[
"Geliefert",
5
]
]
object
ist Mother of all Types 😉
Eine NullReferenceException
bekommt man mit (fast) jeder Methode hin, wenn ich die auf einer null
Referenz aufrufe. Die Try..
-Methoden bilden auch hier keine Ausnahme.
Ja, das ist soweit klar, aber bestimmt nicht das was du wirklich sagen willst.
Bitte mehr Genauigkeit dann gibt es auch weniger Missverständnisse.
BTW: Es gibt durchaus Try..
-Methoden, die eine ArgumentException
werfen, statt einfach ein false
zurück zu geben. (siehe Int32.TryParse)
Ich meinte das etwas anders:
In die Bereiche mit dem X platziert man Container (mit Buttons und ähnlichem Gedöns) - macht also 4 Container. Die Container werden dann je nach Lage angezeigt oder ausgeblendet, so dass immer nur ein Container sichtbar ist.
Der Bereich in der Mitte ist für den Content gedacht.
Die Bereiche mit dem * bleiben komplett frei.
Man setzt also 4 Eigenschaften und gut ist 😉
Ok, dann schau dir mal das Bild an.
Das kann man ganz einfach mit einem Grid-Layout hinbekommen und man blendet die Bereiche (X) je nach Lage ein oder aus.
+-+-----+-+
|*| X |*|
+-+-----+-+
| | | |
| | | |
|X| |X|
| | | |
| | | |
+-+-----+-+
|*| X |*|
+-+-----+-+
Geht dann halt nicht, Pech.
Na dann muss ich meinen Gedanken ja nicht zu Ende denken 😁
Jupp, dazu musst du das Drehen verbieten und den Lagesensor abfragen, um die Rotation für die Controls zu ermitteln.
Aber ob sich das wirklich lohnt?
Wie sieht denn das aus, was du darstellen willst?
Etwa so, und die Buttons (oben links, rechts) sollen quasi immer an der Stelle „bleiben“ egal wie gedreht wird?
[B]#########[B]
+- - - - - - -+
| |
| |
| Content |
| |
| |
+- - - - - - -+
Aus der Sicht der View wird eigentlich nichts gedreht, es ändert sich nur die Höhe und die Breite der View.
AFAIK kann man währed der View-Rotation-Animation eigentlich nichts machen, denn die wird auch vom OS selber vorgenommen.
So wie ich das sehe kommt kurz vor der Rotation die Änderung der Höhe/Breite und dann wird vom OS rotiert.
Also ich kann das so nicht nachvollziehen, denn diese Erweiterungsmethode System.Linq.Enumerable.TakeLast
kann ich leider nicht finden
GitHub: mono/System.Linq.Enumerable
Stellt sich also die Frage, was und woher du dir diese Erweiterungsmethode eingefangen hast. Offiziell sieht das irgendwie nicht aus.
... in wie fern beeinflussen zu viele Threads die Geschwindigkeit des Servers?
Kann man pauschal nicht sagen.
Ich kann auf meinem Rechner x Anwendungen laufen lassen, ohne dass die CPU-Auslastung einen nennenswerten Ausschlag anzeigt (und in jeder Anwendung sind y Threads aktiv).
Die Anzahl der Threads ist unerheblich, es kommt darauf an, was der einzelne Thread macht.
Dann versuche es mal damit
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using System.Windows;
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
Stopwatch m_stopwatch = new Stopwatch();
private async void RepeatButton_Click(object sender, RoutedEventArgs e)
{
await LogAsync();
}
private async Task LogAsync([CallerMemberName]string methodName = null)
{
if (m_stopwatch.IsRunning)
{
m_stopwatch.Stop();
var elapsedMilliseconds = m_stopwatch.ElapsedMilliseconds;
m_stopwatch.Restart();
await Task.Run(() => System.Diagnostics.Debug.WriteLine($"{methodName}: {elapsedMilliseconds}ms"));
}
else
m_stopwatch.Start();
}
}
Ergibt bei mir
RepeatButton_Click: 208ms
RepeatButton_Click: 336ms
RepeatButton_Click: 266ms
RepeatButton_Click: 217ms
RepeatButton_Click: 264ms
RepeatButton_Click: 217ms
RepeatButton_Click: 299ms
RepeatButton_Click: 215ms
RepeatButton_Click: 250ms
RepeatButton_Click: 267ms
RepeatButton_Click: 249ms
RepeatButton_Click: 233ms
RepeatButton_Click: 282ms
RepeatButton_Click: 216ms
RepeatButton_Click: 250ms
RepeatButton_Click: 266ms
RepeatButton_Click: 248ms
RepeatButton_Click: 211ms
RepeatButton_Click: 305ms
RepeatButton_Click: 235ms
RepeatButton_Click: 209ms
RepeatButton_Click: 273ms
RepeatButton_Click: 294ms
RepeatButton_Click: 204ms
RepeatButton_Click: 235ms
RepeatButton_Click: 218ms
RepeatButton_Click: 225ms
Die Spaces hab ich hinzugefügt, damit ++nicht ++in eine URL umgewandelt wird.
Was man aber auch so http://localhost:50000
(TT-Tag)
oder so
http://localhost:50000
(PRE-Tag)
schreiben kann 😉
@dannoe
Der TE schreibt nirgends, dass er Strg-V
abfängt. Er hat eine spezielle Tasten-Kombination (wohl ein Globaler Hotkey) mit der er sein "Zwischenablage-Verwaltungs-Programm" aufruft.
@maYer
Du kannst auch mal mit WM_PASTE
herumspielen.
Ein Doppel-Klick-Ereignis tritt ein, wenn zwei einfache Klicks innerhalb einer bestimmten Zeitspanne innerhalb einer bestimmten Entfernung (kann der Benutzer jeweils selber anpassen) erfolgen.
Der erste einfache Klick - der dann gleich zum Doppel-Klick werden soll - wird auch als einfacher Klick verarbeitet.
Es gibt also kein Doppel-Klick-Ereignis ohne das Klick-Ereignis.
Meine Vermutung:
Es hängt bei der Verarbeitung des normalen Klick-Ereignis.
Du weißt, dass so ein Visual aus drei Dateien besteht?*XAML: foo.xaml
*CS: foo.xaml.cs
*Generated CS: foo.g.i.cs
(wird von VS aus der foo.xaml
erzeugt)
Wenn du den Namespace ändern möchtest, dann musst du die Änderungen sowohl in der \*.xaml
als auch in der \*.xaml.cs
vornehmen.
Die Reihenfolge ist egal, aber erst wenn du den Namespace in beiden Dateien geändert hast, dann kann VS die korrekte \*.g.i.cs
dazu erzeugen und dann klappt es auch mit dem Nachbarn.
Alles, was während des Änderns (zwei Dateien gleichzeitig bearbeiten geht halt nicht) an Fehlern angezeigt wird, ist nachvollziehbar und kann vernachlässigt werden.
Nun, der Code sieht ja schon wieder anders aus ... aber die Richtung stimmt schon mal 😁
//start reading response
int read = response.Read(buffer, 0, buffer.Length);
// We get f.i.
// ttttttttt!TERbbbbbbb
// read is 20
//search beginning of binary-part
int intPosByte2 = findByteArray(buffer, Encoding.ASCII.GetBytes("!TER")) + 4; // + 4 da bei ASCII 4 Zeichen 4 Bytes sind
// intPosByte2 is 13
// now write form buffer position intPosReadByte2 (13) the read (20) - intPosReadByte2 (13) (=>7) bytes to the stream
if ( read - intPosByte2 > 0 )
fsContent.Write(buffer, intPosByte2, read - intPosByte2);
//then read and write content
read = response.Read(buffer, 0, buffer.Length);
while (read > 0)
{
fsContent.Write(buffer, 0, read);
read = response.Read(buffer, 0, buffer.Length);
}
Dein Code setzt allerdings auch auf das Prinzip Hoffnung ... das der Trenner !TER
auch immer innerhalb des ersten Blocks komplett auftaucht.
Ein einfaches Problem bekommst du, wenn das so aussehen würde
tttttttttttttttttttt
tttt!TERbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbb
bbbbb
und richtig blöd wird es, wenn dieser Trenner genau zwischen zwei Blöcken zu finden ist
tttttttttttttttttt!T
ERbbbbbbbbbbbbbbbbbb
bbbbbbbbbbbbbbbbbbbb
bbbbb
Also bei mir sieht so ein UserControl so aus
namespace WpfApp24.Controls
{
/// <summary>
/// Interaktionslogik für TimePicker.xaml
/// </summary>
public partial class TimePicker : UserControl
{
public TimePicker()
{
InitializeComponent();
}
}
}
<UserControl x:Class="WpfApp24.Controls.TimePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfApp24.Controls"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</UserControl>
Nach dem Lesen des ersten Blocks (3*1024 Bytes) stehen ja am Anfang die unnötigen und am Ende die benötigten Daten.
Allerdings behälst du die unnötigen und überschreibst die benötigten Bytes.
Speziell zum Async-Reentrancy kannst du dir auch diesen Link anschauen, dort gibt es 5 Pattern (u.a. auch einen mit einem SemaphoreSlim
, der deinem gedachten EventWaitHandle
am nächsten kommt).
Mit deiner Variante hast du dir einen schönen DeadLock gebaut
EventWaitHandle _setupAllowedHandle = new EventWaitHandle(true, EventResetMode.AutoReset);
async Task SetupAsync()
{
_setupAllowedHandle.WaitOne();
Func<Task> setupAsync = async () =>
{
await Task.Delay(2000).ConfigureAwait(false);
};
await setupAsync();
_setupAllowedHandle.Set();
}
private async void button1_Click(object sender, EventArgs e)
{
await SetupAsync();
}
Einfach innerhalb von 2 Sekunden zweimal auf den Button hauen.
Den Lock brauchst du nicht, denn die Aufrufe erfolgen dort immer vom UI Thread 😉
Und man muss darauf achten, dass wir es hier mit BigEndian zu tun haben.
Mit einem passenden BinaryReader/Writer (der BigEndian verwendet) kann man so ein Byte-Array dann sehr schön lesen und schreiben.
Es ist immer sehr hilfreich wenn man zeigt was man als Eingangsdaten hat und was man als Rückgabewert erwartet.
Also, was für eine Bytefolge hast du und welchen Datum/Zeitwert soll das darstellen?
@emuuu
AFAIK Bei SQL-NULL ist der zurückgelieferte Wert DBNull
und eben nicht null
. Der ??
Operator hilft hier also so nicht.
Wenn du innerhalb der Methode mit await
hantierst, dann musst du die Methode auch als async
deklarieren.
Somit wird aus
public string GetResponseString()
{
string result;
result = ...
return result;
}
ein
public async Task<string> GetResponseStringAsync()
{
string result;
result = await ...
return result;
}
Da gibt es was von Rati*pharm Microsoft: Await, SynchronizationContext, and Console Apps
Beim Debuggen im Menü unter Debuggen - Fenster - Tasks
.
Das Fenster selber heißt dann sinnigerweise Aufgaben
. 😁
Was für eine Reaktion der Oberfläche erwartest du denn?
Bei TextBox.IsReadOnly
ändert sich an der Darstellung rein gar nichts. Hast du wirklich probiert den Text in der TextBox
zu ändern, wenn IsReadOnly
auf true
steht?
Task.Result
oder auch Task.Wait
(was intern durch Task.Result
aufgerufen wird) blockiert den aktuellen Thread.
Wer async
sagt muss auch await
sagen!
Darum
private async void Form1_Load(object sender, EventArgs e)
{
if(await performLogin())
{
Console.WriteLine("Login DONE!");
}
}
Das waitTillReadyState
kann man schöner und sauberer mit TaskCompletionSource
lösen. Einfach mal nach Beispielen suchen.
Ich vermute mal, du hast das Beispiel zu stark zusammengestrichen.
Kann es sein, dass dein originaler Code in irgendeiner Art etwas mit dem Image veranstaltet? Das geht aus deiner Beschreibung nicht hevor, nur das da auch ein Image angezeigt wird, aber nicht ob das Image in diesem Codeteil eine weitere Rolle spielt.
async/await hier hier der falsche Ansatz, da du deine Asynchrone Operation startest und direkt darauf wartest.
Du blockierst also deine GUI und hast damit keinen Nutzen.
Und ich dachte, das man mit async/await eben genau nicht blockiert.
Mit VS2017 läuft dieser Code einwandfrei und nicht blockierend.
Der Browser setzt einen GET Request auf der Url ab, aber dafür gibt es keine passende Methode in deinem Controller.
Visuelle Änderungen werden verzögert ausgeführt. Das Window sammelt alle Änderungen und stellt diese dann in einem Rutsch dar.
Den Fokus kann man nur auf Elemente setzen, die auch sichtbar und aktiviert sind. Vor dem Tab-Wechsel ist die TextBox aber nicht sichtbar und kann auch den Fokus nicht erhalten.
Dieses sichtbar machen der TextBox erfolgt aber wie oben erwähnt verzögert.
Wenn die View dann alles abgearbeitet und dargestellt hat, dann kann man auch den Fokus auf die TextBox legen. Aus diesem Grund muss man beim Dispatcher-Aufruf auch noch DispatcherPriority.ApplicationIdle
(bzw. alle Werte ≤ DispatcherPriority.Render
funktionieren) mitgeben, sonst erfolgt der Aufruf zu früh.
Und die Erzeugung der Verzeichnisstruktur ist definitiv eine Aufgabe, die die Datenschicht zu erledigen hat.
Genauso wie du mit den anderen Daten umgehst.
Irgendwo schreibst du konkret die Daten in ... eine Datenbank/in eine Datei. Wohin konkret soll(te) der Anwendung egal sein.
Wenn du den Compiler komplett neu schreibst und die grundlegende Vorgehensweise komplett auf den Kopf stellst, ja 😁
Der Zähler wird NICHT zurückgesetzt, sondern neu erzeugt (auf dem Stack)
Das Problem kann man sehr leicht nachsstellen mit
<Window x:Class="WpfApp17.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp17"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl Name="TabControl">
<TabItem Name="First_TabItem" Header="First">
<StackPanel>
<TextBox Name="First_TextBox"/>
</StackPanel>
</TabItem>
<TabItem Name="Second_TabItem" Header="Second">
<StackPanel>
<TextBox Name="Second_TextBox"/>
</StackPanel>
</TabItem>
</TabControl>
<Button Grid.Row="1" Content="Next" Click="Button_Click"/>
</Grid>
</Window>
und im CodeBehind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Second_TabItem.IsSelected = true;
Second_TextBox.Focus();
}
}
Der erste Klick auf den Button Next bewirkt das Second_TabItem
sichtbar wird, allerdings nicht, dass der Fokus auch auf der Second_TextBox
ist.
Ein weiterer Klick auf den Button Next setzt dann korrekt den Fokus auf die Second_TextBox
.
Damit das mit einem Klick/Aufruf funktioniert benötigt man den Dispatcher
private async void Button_Click(object sender, RoutedEventArgs e)
{
Second_TabItem.IsSelected = true;
// Second_TextBox.Focus();
await Dispatcher.InvokeAsync(
() => Second_TextBox.Focus(),
System.Windows.Threading.DispatcherPriority.ApplicationIdle);
}
Wo ist das Problem?
Wenn du mit einer WebApi sprichst, dann behälst du ja auch nicht den JSON string, sondern packst den in eine sinnvolle Klasse zum Bearbeiten innerhalb der Anwendung. Und wenn das wieder zurück geht, dann wird aus der Klasse wieder ein JSON string und ab zum Service geschickt.
Oder schleppst du doch den string durch deine Anwendung? Dann will ich nichts gesagt haben
Schau dir mal QuickIO.NET - Performante Dateioperationen an
Starte den Vorgang asynchron, dann kann der UI-Thread auch das GIF weiter animieren
Warum hast du keinen Typen für die Koordinaten deklariert?
Dieses Gehampel - das ist es leider - mit dem double[]
steht einem doch nur zwischen den Füßen rum.
Und wenn du alles richtig gemacht hast, dann sieht dein Code so aus
public List<Koordinate> löscheDoppelteSchnittpunkte(List<Koordinate> schnittpunktliste)
{
return schnittpunktliste.Distinct().ToList();
}