Laden...
B
BlueSubmarine
myCSharp.de - Member
4
Themen
15
Beiträge
Letzte Aktivität
vor einem Jahr
Dabei seit
07.09.2016
Erstellt vor einem Jahr

Ah okay. Danke.

Erstellt vor einem Jahr

@Abt: Funktioniert. Perfekt. Besten Dank!

JsonContext.cs

using System.Text.Json.Serialization;

[JsonSourceGenerationOptions(WriteIndented = true)]
[JsonSerializable(typeof(WeatherForecast))]
internal partial class SourceGenerationContext : JsonSerializerContext
{
}

Program.cs

using System.Text;
using System.Text.Json;

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

internal class Program
{
    static void Main(string[] args)
    {
        try
        {
            var weatherForecast = new WeatherForecast()
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            var jsonString = JsonSerializer.Serialize(weatherForecast!, SourceGenerationContext.Default.WeatherForecast);
            var byteArray = Encoding.UTF8.GetBytes(jsonString);

            var restoredJsonString = Encoding.UTF8.GetString(byteArray);
            var restoredWeatherForecast = JsonSerializer.Deserialize<WeatherForecast>(restoredJsonString, SourceGenerationContext.Default.WeatherForecast);

            Console.WriteLine(restoredWeatherForecast.Summary);
            Console.WriteLine(restoredWeatherForecast.TemperatureCelsius);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        Console.ReadKey();
    }
}

Eine Frage hab ich allerdings noch. Was bewirkt das Ausrufezeichen hinter weatherForecast?

var jsonString = JsonSerializer.Serialize(weatherForecast!, SourceGenerationContext.Default.WeatherForecast);

@david.m: Funktioniert auch mit .NET 7.

Erstellt vor einem Jahr

Ich glaube du hast vergessen in deiner .csproj <PublishAot>true</PublishAot> hinzuzufügen. Bei deinem Quellcode bekomme ich folgenden Output:

Object as Json: {}
Restored Json: {}
Unhandled Exception: System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'WeatherForecast'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'WeatherForecast'.
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack&, Utf8JsonReader&, NotSupportedException) + 0x33a
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader&, Type, JsonSerializerOptions, ReadStack&, T&) + 0xd3
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader&, Type, JsonSerializerOptions, ReadStack&, T&, Boolean&) + 0x225
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader&, JsonSerializerOptions, ReadStack&) + 0x350
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1, JsonTypeInfo`1, Nullable`1) + 0xfe
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1, JsonTypeInfo`1) + 0x108
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String, JsonSerializerOptions) + 0x4c
   at Program.Main(String[] args) + 0x11c
   at JsonSerializerConsole!<BaseAddress>+0x20ea69
Erstellt vor einem Jahr

Also irgendwie habe ich glaube ich gerade ein Brett vorm Kopf. Sollte folgendes nicht eigentlich funktionieren?

using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

public class WeatherForecast
{
    [JsonConstructorAttribute]
    public WeatherForecast(DateTimeOffset Date, int TemperatureCelsius, string? Summary)
    {
        this.Date = Date;
        this.TemperatureCelsius = TemperatureCelsius;
        this.Summary = Summary;
    }

    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

internal class Program
{
    static void Main(string[] args)
    {
        try
        {
            var weatherForecast = new WeatherForecast(DateTime.Parse("2019-08-01"), 25, "Hot");

            var jsonString = JsonSerializer.Serialize(weatherForecast);
            var byteArray = Encoding.UTF8.GetBytes(jsonString);

            var restoredJsonString = Encoding.UTF8.GetString(byteArray);
            var restoredWeatherForecast = JsonSerializer.Deserialize<WeatherForecast>(restoredJsonString);

            Console.WriteLine(restoredWeatherForecast.Summary);
            Console.WriteLine(restoredWeatherForecast.TemperatureCelsius);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        Console.ReadKey();
    }
}

Bekomme aber immer noch folgende Exception:

System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'WeatherForecast'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'WeatherForecast'.
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack&, Utf8JsonReader&, NotSupportedException) + 0x1fe
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader&, Type, JsonSerializerOptions, ReadStack&, T&) + 0xb2
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader&, Type, JsonSerializerOptions, ReadStack&, T&) + 0x1ec
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader&, JsonSerializerOptions, ReadStack&) + 0x34f
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1, JsonTypeInfo, Nullable`1) + 0x109
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1, JsonTypeInfo) + 0xf5
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String, JsonSerializerOptions) + 0x58
   at Program.Main(String[]) + 0xe3
Erstellt vor einem Jahr

@Palladin007: Hmmm ja, das entspricht dann meinem zweiten Ansatz bzw. zweiten Beitrag. Leider funktioniert das auch nicht. Siehst du den Fehler, den ich gemacht habe?

@Abt: Also entweder verstehe ich die Fehlermeldung nicht richtig oder das betrifft quasi jede Art von Konstruktor. Ist also nicht umsetzbar.

Erstellt vor einem Jahr

Ich habe nochmal was anderes ausprobiert. Leider funktioniert es nur wieder ohne NativeAot.

using System.Text;
using System.Text.Json;

public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

internal class Program
{
    static void Main(string[] args)
    {
        try
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            var jsonString = JsonSerializer.Serialize(weatherForecast);
            var byteArray = Encoding.UTF8.GetBytes(jsonString);

            var restoredJsonString = Encoding.UTF8.GetString(byteArray);
            var restoredWeatherForecast = JsonSerializer.Deserialize<WeatherForecast>(restoredJsonString);

            Console.WriteLine(restoredWeatherForecast.Summary);
            Console.WriteLine(restoredWeatherForecast.TemperatureCelsius);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        Console.ReadKey();
    }
}

Ausgabe IL exe:

Hot
25

Ausgabe native exe:

System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'WeatherForecast'. Path: $ | LineNumber: 0 | BytePositionInLine: 1.
 ---> System.NotSupportedException: Deserialization of types without a parameterless constructor, a singular parameterized constructor, or a parameterized constructor annotated with 'JsonConstructorAttribute' is not supported. Type 'WeatherForecast'.
   --- End of inner exception stack trace ---
   at System.Text.Json.ThrowHelper.ThrowNotSupportedException(ReadStack&, Utf8JsonReader&, NotSupportedException) + 0x1fe
   at System.Text.Json.Serialization.Converters.ObjectDefaultConverter`1.OnTryRead(Utf8JsonReader&, Type, JsonSerializerOptions, ReadStack&, T&) + 0xb2
   at System.Text.Json.Serialization.JsonConverter`1.TryRead(Utf8JsonReader&, Type, JsonSerializerOptions, ReadStack&, T&) + 0x1ec
   at System.Text.Json.Serialization.JsonConverter`1.ReadCore(Utf8JsonReader&, JsonSerializerOptions, ReadStack&) + 0x34f
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1, JsonTypeInfo, Nullable`1) + 0x109
   at System.Text.Json.JsonSerializer.ReadFromSpan[TValue](ReadOnlySpan`1, JsonTypeInfo) + 0xf5
   at System.Text.Json.JsonSerializer.Deserialize[TValue](String, JsonSerializerOptions) + 0x58
   at Program.Main(String[]) + 0xe3
Erstellt vor einem Jahr

Guten Tag zusammen,

ich benötige ein Object als Byte Array und muss dieses auch wieder von einem Byte Array zu einem Object zurückkonvertieren können. Das klingt erstmal nach keinem Problem, allerdings wird das Programm mit NativeAot kompiliert und dann funktioniert es nicht mehr. Hier mein Codeansatz:

BinarySerializer.cs

using System.Runtime.Serialization.Formatters.Binary;

public class BinarySerializer
{
    public static byte[] Serialize(object objectToSerialize)
    {
        var binaryFormatter = new BinaryFormatter();
        var memoryStream = new MemoryStream();
        binaryFormatter.Serialize(memoryStream, objectToSerialize);
        return memoryStream.ToArray();
    }

    public static object Deserialize(byte[] bytesToDeserialize)
    {
        var memoryStream = new MemoryStream();
        var binaryFormatter = new BinaryFormatter();
        memoryStream.Write(bytesToDeserialize, 0, bytesToDeserialize.Length);
        memoryStream.Position = 0;
        return binaryFormatter.Deserialize(memoryStream);
    }
}

Program.cs

[Serializable]
public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string? Summary { get; set; }
}

internal class Program
{
    static void Main(string[] args)
    {
        try
        {
            var weatherForecast = new WeatherForecast
            {
                Date = DateTime.Parse("2019-08-01"),
                TemperatureCelsius = 25,
                Summary = "Hot"
            };

            var byteArray = BinarySerializer.Serialize(weatherForecast);

            var restoredWeatherForecast = (WeatherForecast)BinarySerializer.Deserialize(byteArray);

            Console.WriteLine(restoredWeatherForecast.Summary);
            Console.WriteLine(restoredWeatherForecast.TemperatureCelsius);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }

        Console.ReadKey();
    }
}

.csproj

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
	  <PublishAot>true</PublishAot>
	  <EnableUnsafeBinaryFormatterSerialization>true</EnableUnsafeBinaryFormatterSerialization>
	  <OutputType>Exe</OutputType>
    <TargetFramework>net7.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>

</Project>

Wenn ich nun die IL exe starte. Ausgabe (wie gewünscht):

Hot
25

Wenn ich dann die native exe starte. Ausgabe:

System.TypeInitializationException: A type initializer threw an exception. To determine which type, inspect the InnerException's StackTrace property.
 ---> System.IO.FileNotFoundException: Cannot load assembly 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'. No metadata found for this assembly.
   at System.Reflection.Runtime.General.ReflectionCoreCallbacksImplementation.Load(AssemblyName, Boolean) + 0x7d
   at System.Runtime.Serialization.Formatters.Binary.Converter..cctor() + 0x2e3
   at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0xc6
   --- End of inner exception stack trace ---
   at System.Runtime.CompilerServices.ClassConstructorRunner.EnsureClassConstructorRun(StaticClassConstructionContext*) + 0x167
   at System.Runtime.CompilerServices.ClassConstructorRunner.CheckStaticClassConstructionReturnGCStaticBase(StaticClassConstructionContext*, Object) + 0xd
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.GetAssemblyId(WriteObjectInfo) + 0x68
   at System.Runtime.Serialization.Formatters.Binary.ObjectWriter.Serialize(Object, BinaryFormatterWriter) + 0x1ed
   at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Serialize(Stream, Object) + 0xef
   at BinarySerializer.Serialize(Object) + 0x64
   at Program.Main(String[]) + 0x88

Hoffe es gibt da eine Möglichkeit die die gewünschte Funktion mit NativeAot funktional macht. Welchen Klassen am Ende benutzt werden ist ja egal. Hauptsach es läuft. Aber nach Möglichkeit ohne Third Party Libraries. Bin auf eure Antworten gespannt.

Mit freundlichen Grüßen

Erstellt vor 2 Jahren

Naja der Unterschied ist das der Code mit Threads funktioniert, aber nicht mit Tasks. Ich würde dennoch lieber Tasks verwenden, weil Thread.Abort nur im .NET Framework funktioniert und eben eigentlich nicht genutzt werden sollte.

Es handelt sich um ein sehr simples Konstrukt. Es gibt den Hauptthread und eben genau den einen Helferthread. Der Hauptthread teilt sich in 2 Bereiche auf und der Helferthread darf nur in Bereich 2 mitlaufen. Bestimmte Bedingungen in Bereich 2 können dazu führen das der Hauptthread wieder in Bereich 1 übergeht und die ersten Zeilen des Bereich 1 dafür sorgen das der Helferthread gestoppt wird, bis der Hauptthread irgendwann wieder in Bereich 2 übergeht und der Helferthread wieder gestartet wird. Also quasi:

Hauptthread Bereich 1 -> Helferthread gestoppt
Hauptthread Bereich 2 -> Helferthread läuft

Erstellt vor 2 Jahren

Danke für eure Antworten. Im nachfolgenden Beispiel hätte ich genau das was ich bräuchte, nur leider läuft der Code nur mit dem .NET Framework und nicht mit .NET 6 oder 7. Wie würde der Code aussehen, wenn er unter .NET 6 oder 7 laufen würde?


using System;
using System.Threading;

namespace ThreadAbortTest
{
    class App
    {
        private Thread DoesSomethingThread { get; set; } = null;

        public void Run()
        {
            while (true)
            {
                if (DoesSomethingThread != null)
                {
                    DoesSomethingThread.Abort();
                }

                DoesSomethingThread = new Thread(() =>
                {
                    while (true)
                    {
                        Console.Write("Active!");

                        Thread.Sleep(5000);
                    }
                });

                DoesSomethingThread.Start();

                Thread.Sleep(15000);
            }
        }
    }
}

Erstellt vor 2 Jahren

Guten abend,

ich habe einen Codeabschnitt der öfters mal ausgeführt wird und der einen Task startet. Da dieser Abschnitt öfters ausgeführt wird würde er jedesmal einen Task mehr starten. Es soll aber immer nur ein Task gleichzeitig laufen. Leider klappt das canceln des alten Tasks nicht wodurch sich die laufenden Tasks anhäufen. Warum? Freue mich über jede Hilfe.

Hier ein Beispiel:


using System;
using System.Threading;
using System.Threading.Tasks;

namespace CancelTaskTest
{
    class App
    {
        private CancellationTokenSource TaskCancel { get; set; } = new CancellationTokenSource();

        public void Run()
        {
            while (true)
            {
                TaskCancel.Cancel();
                TaskCancel = new CancellationTokenSource();

                Task.Run(() =>
                {
                    while (true)
                    {
                        Console.Write("Active!");

                        Thread.Sleep(5000);

                        if (TaskCancel.Token.IsCancellationRequested)
                        {
                            Console.Write("Cancelled!"); // Never gets called, why?
                            return;
                        }
                    }
                }, TaskCancel.Token);

                Thread.Sleep(15000);
            }
        }
    }
}

Mit freundlichen Grüßen