Cross-Thread-Mutation mit Task – ist das erlaubt?C#

Ein Treffpunkt für C#-Programmierer
Anonymous
 Cross-Thread-Mutation mit Task – ist das erlaubt?

Post by Anonymous »

Ich bin nicht der C#-Typ, aber ich habe ein Projekt, in dem ich an einigen Stellen etwas Ähnliches gefunden habe

Code: Select all

public class Program
{
private static int[] value = new int[1];

public static async Task Main()
{
Console.WriteLine($"{(Thread.CurrentThread.Name.IsEmpty() ? "Main": Thread.CurrentThread.Name)}/{Thread.CurrentThread.ManagedThreadId}");
value[0] = 123;

await Task.Yield();

Console.WriteLine($"{Thread.CurrentThread.Name}/{Thread.CurrentThread.ManagedThreadId}");
Console.WriteLine($"value={value[0]}");

if (value[0] != 123) throw new Exception("Gotcha!");
}
}

// produces:
// Main/1
// .NET ThreadPool Worker/5
// value=123
Zuerst habe ich angenommen, dass es illegal ist (Cross-Thread-Mutation eines unsynchronisierten Werts), aber dann habe ich einen halben Tag damit verbracht, das zu beweisen, und es ist mir nicht gelungen, ein Beispiel zu erstellen, das das Problem wirklich aufdecken würde (.net6.0, Linux, Release-Build).
Gibt es etwas in async/await, das eine Speicherbarriere einrichtet und tatsächlich sicherstellt, dass der Code funktioniert?
Update (danke an alle für Kommentare).
Zur Klarstellung:
  • es stimmt, dass nichts parallel läuft
  • es stimmt auch, dass mehrere Threads beteiligt sind und diese Threads auf den gemeinsam genutzten Speicherort zugreifen
Vielleicht ist das Beispiel zu stark vereinfacht, lassen Sie es mich etwas umformulieren:

Code: Select all

        async Task DoRequestAndStoreResult(int[] data)
{
data[0] = 42; // mutation, first thread
await Task.Yield(); // some actual async work that causes thread switch
data[1] = 42; // mutation, second thread
}

var result = new int[2];
await DoRequestAndStoreResult(result);
// read out and process result
Ich frage mich, ob diese Art von Code korrekt ist, oder ob er mit etwas Pech (mehr Threads beteiligt,
derselbe Thread für verschiedene Teile der Ausführung ausgewählt, Thread-lokale Caches nicht mehr synchron sein usw.)
kann fehlschlagen, wenn der Code veraltete/beschädigte Werte sieht.
m.

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post