myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Basistechnologien und allgemeine .NET-Klassen » Wird ein Objekt, das an einen Task übergeben wird, bei Veränderungen vom Main Thread mit verändert?
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

geschlossen (weitere Infos)
Zum Ende der Seite springen  

Wird ein Objekt, das an einen Task übergeben wird, bei Veränderungen vom Main Thread mit verändert?

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32


ck82 ist offline

Wird ein Objekt, das an einen Task übergeben wird, bei Veränderungen vom Main Thread mit verändert?

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo liebe Pro`s,

hoffe ihr könnt einem Noob etwas unter die Arme greifen.

Stellen wir uns vor ich habe ein Objekt meiner Klasse generiert

MeineKlasse meinObjekt = new MeineKlasse();

Nun möchte ich zum einen unabhängig vom bestehenden Programmlauf einen Task starten und meinObjekt übergeben:

Task.Run(() => meinTask(meinObjekt));

Der Task arbeitet nun mit den Daten von meinemObjekt.

Gleichzeitig läuft das Programm weiter und modifziert ebenfalls meinObjekt.
Wie wirkt es sich auf "meinObjekt" aus?

A: Es wurde eine Kopie (bzw. ein neues unabhängiges Objekt) erstellt und Änderungen egal an welchem der beiden Objekte wirkt sich nicht auf das jeweils andere aus.

B: Änderungen der einzelnen Objekte würde auf das andere auswirken. Z.B. würde im Task ein enthaltener string geändert, würde es in dem anderen Objekt die Daten des Task enthalten?

Hoffe ihr könnt mir helfen.

Gruß
ck

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von ck82 am 25.09.2020 15:11.

25.09.2020 15:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von ck82:
Gleichzeitig läuft das Programm weiter und modifziert ebenfalls meinObjekt.
Wie wirkt es sich auf "meinObjekt" aus?

Im dümmsten Fall eine Race Condition; daher sollte man die parallele Verwendung von Objekten auch - meistens - vermeiden.
Zudem muss natürlich ein Objekt vollständig Thread-Safe sein.

Nur weil Du einen Task erstellst ändert das ja das Referenzverhalten von Objekten nicht.
Daher wird auch nicht "einfach so" eine Kopie erstellt.

Es ist immer besser, wenn Du mal erzählst, was Dein Vorhaben ist; dann kann man Dir sagen, wie man sowas löst.
Es macht immer wenig Sinn über ein Vorhaben zu reden, das man evtl. ganz anders lösen sollte.
25.09.2020 15:44 Beiträge des Benutzers | zu Buddylist hinzufügen
gfoidl gfoidl ist männlich
myCSharp.de-Team

avatar-2894.jpg


Dabei seit: 07.06.2009
Beiträge: 6.681
Entwicklungsumgebung: VS 2019
Herkunft: Waidring


gfoidl ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo ck82,

ich stimme Abt da ganz zu.

Zitat von Abt:
Daher wird auch nicht "einfach so" eine Kopie erstellt.

Das ist eben die Krux dabei, dass beide Threads (der Main-Thread, sowie jener der die Aktion von Task.Run mit einem ThreadPool-Thread ausführt) auf dasselbe Objekt arbeiten und du nicht bestimmen kann wer wann welche Ändeurng zuerst durchführt. Es ist somit durchaus möglich, dass in den Daten deines Objekts Müll entsteht. Das ist die von Abt erwähnte "Race Condition".

Abhilfen gibt es dafür ein paar:
  • Thread-Synchronisierungen (suche mal danach, da gibt es Lektüre fürs WE -- Vorzugsweise:  Basic Synchronization aus Threading in C# / Joseph Albahari)

  • immutable Typen verwenden, d.h. Typen die nach der Instanzierung nicht mehr geändert werden können und somit gibt es kein Race
    (Anm.: das ist mit ein Grund warum mit C#9 Records eingeführt werden, neben dem weniger Tipparbeit für Datenklassen)

  • asynchron arbeiten, aber ohne gleichzeitige Zugriffe auf das Objekt, z.B. mittels einer Pipeline in der das Objekt von "Station zu Station" gereicht wird
Aber berücksichtige

Zitat:
erzählst, was Dein Vorhaben ist

mfG Gü
25.09.2020 16:04 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo Abt,

hab grad eben mal schnell in einem kleinen Programm nachgestellt und es ändert mir meine Werte vom Objekt im Hauptprogramm. Somit eigentlich nicht zu verwenden.

Mein Hauptprogramm arbeitet in einer Schleife Objekte ab.

Mit dem Task wollte ich Zeit sparen. Der Task soll einfach ein paar Sachen in einer SQL-Datenbank speichern. Das ganze ausgelagert als Task, da dieser vom Programm unabhängig arbeiten sollte.

Problem ist nur, wenn das Hauptprogramm die neuen Daten lädt (wieder am Anfang der Schleife) und wie jetzt auch bestätigt überschreibt, speichert es mir in dem Task ggf. zwischenzeitlich geänderte Daten.

Hoffe die Erklärung war einigermaßen verständlich.

Gruß
ck
25.09.2020 16:09 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Werte in eine Datenbank speichern gilt als IO Operation, und dafür nutzt man die asynchrone Programmierung und nicht die parallele Programmierung.
Und wenn Du ein Objekt aus Deiner Logik mit einer Datenbank-Operation teilst, dann hört sich das nach einem ganz arg bösen Architekturfehler an ;-)

Wenn Du Dich an die Grundprinzipien von  [Artikel] Drei-Schichten-Architektur kann es eigentlich keine Race Condition zwischen Logik und Datenbank geben.
25.09.2020 16:14 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Nachfolgend der kurze Test von eben.
Gibt es eine Möglichkeit, das ich in Task eine Kopie erhalte, welche sich nicht auf das Hauptprogramm auswirkt.

C#-Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskRunTestLoeschen
{
    class Program
    {
        static void Main(string[] args)
        {
            meineKlasse mek = new meineKlasse();
            mek.test = 1000;
            Task.Run(() => MeinTask(mek));

            for (int i = 1000; i > 0; i--)
            {
                Console.WriteLine(mek.test--);
                Console.WriteLine("Der Wert von MEK im Programm ist: " + mek.test);
            }
            Console.ReadKey();

        }




        private static async void MeinTask(meineKlasse mek)
        {
            List<int> intList = new List<int>();

            for(int i = mek.test; i > 0; i--)
            {
                mek.test = 5000;
                System.Threading.Thread.Sleep(1);
            }
            System.Threading.Thread.Sleep(20000);
            for(int i = 0; i < intList.Count; i++)
            {
                Console.WriteLine(intList[i]);
                Console.WriteLine("Der Wert von MEK im Task ist: " + mek.test);
                Console.WriteLine("Der Wert von MEK im Task ist erhöht: " + (mek.test+i));
            }
        }

    }



    public class meineKlasse
    {
        public int test { get; set; }
    }
}
25.09.2020 16:29 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Warum willst Du denn jetzt eine Kopie? Das ist der falsche Weg.
Was ist denn der Grund, dass Du es nicht richtig machen willst?
25.09.2020 16:42 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Noch etwas realistischer dargestellt.
So etwas würde mein Programm arbeiten (stark vereinfacht)

C#-Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace TaskRunTestLoeschen
{
    class Program
    {
        static void Main(string[] args)
        {
            // meine Klasse
            meineKlasse mek = new meineKlasse();
            // wert 1000
            mek.test = 1000;


            for (int i = 1000; i > 0; i--)
            {
                /*
                 Hier sind irgendwelche Bearbeitungen
                 */

                mek.test = i;

                Task.Run(() => MeinTask(mek));


                Console.WriteLine("Der Wert von MEK im Programm ist: " + mek.test);

                /*
                 Weitere Bearbeitungen
                 */

            }
            Console.ReadKey();

        }




        private static async void MeinTask(meineKlasse mek)
        {
            // Speichere etwas in die SQL-Datenbank

            string abfrage = "INSERT INTO Datenbank (Felder1) VALUES (@Value);";
            using (connection = new SqlConnection(connectionString))
            {
                connection.Open();
                // usw......
            }
    }



    public class meineKlasse
    {
        public int test { get; set; }
    }
}

Ich war der Meinung es arbeitet die Schleife ab und öffnet nacheinander 1000 Tasks.

Beim ersten Task würde 1000 mitgegeben
beim zweiten Task würde 999 mitgegeben
usw.

Aber jetzt läuft es so es gibt beim ersten Task 1000 mit
Wenn der Task jetzt aber länger dauert, dann würde das Progr.
beim zweiten Task vieleicht 990 mitgeben
--> Somit bereits die Werte vom 10 Task
25.09.2020 16:45 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das Problem mit Tasks ist: wendet man sie falsch an, weil man sie zB nicht versteht, macht man am Ende mehr kaputt als dass man erreicht.

Zitat:
Aber jetzt läuft es so es gibt beim ersten Task 1000 mit
Wenn der Task jetzt aber länger dauert, dann würde das Progr.
beim zweiten Task vieleicht 990 mitgeben
--> Somit bereits die Werte vom 10 Task

Das ist auch absolut korrekt so und verstehst Du, sobald Du Tasks verstehst.
Es gibt keine Garantie auf eine Ablauf-Reihenfolge. Aber Tasks ist leider ein Thema, bei dem man mit Try and Error nicht viel erreichen wird. Du musst Tasks verstehen - und dazu gehört leider das Konzept dahinter. Steht aber alles in den Docs.

Du versuchst ein asynchrones Problem mit Parallelität zu lösen; das wird aber halt nicht klappen.

Daher: arbeite mit asynchroner Programmierung, beachte  [Artikel] Drei-Schichten-Architektur und Dein Problem ist ohne Nebenwirkungen gelöst.
25.09.2020 16:48 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das Programm läuft die Schleife 1000 mal durch.

Dann produziert es 1000 Tasks.

z.B.

Task 1000
Task 999
Task 998
...

Das Programm müsste die Task nacheinander abarbeiten wie aufgerufen.

Wenn ich jedem Task nun FIX seinen Wert mitgeben könnte, dann würde es so aussehen.

Task 1000 (FIX 1000) --> D.H. in Datenbank Wert = 1000
Task 999 (FIX 999) --> Datenbank Wert = 999
Task 998 (FIX 998) --> Datenbank Wert = 998
...

Der Task müsste nur mit einen neuen Objekt arbeiten, was unabhängig ist vom Programm. Und das würde mich interessieren ob hier jemand eine Idee hat.

Voreil wäre Programm ist bereits bei 0 und im panding sind noch X Tasks mit den jeweils FIXEN Werten zum speichern.

Oder liege ich hier komplett daneben?

In dem Fall müsste ich vermutlich das ganze Programm synchron laufen lassen.
Dann müsste das Programm halt immer auf die Datenbank-Speicherung, etc. warten. Und das Programm (der Hauptteil) würde langsamer durchlaufen.
25.09.2020 16:58 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Jo, so wendet man halt auch einfach Tasks auch nicht an.
Aber ich habs Dir nun mehrmals gesagt: schau Dir an wie Tasks funktionieren und wie man sie anwenden soll.
Aber hab jetzt auch keine große Lust mich hundert mal zu wiederholen ;-)

Wenn Du die Tipps nicht annehmen willst, dann ist das halt so.
Kann Dich da auch nicht zu zwingen.
25.09.2020 17:13 Beiträge des Benutzers | zu Buddylist hinzufügen
chilic
myCSharp.de-Poweruser/ Experte

Dabei seit: 12.02.2010
Beiträge: 2.062


chilic ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zu deinen Zahlen im Task möchte ich anmerken, schau dir genau an was du da machst.

Du erstellst EIN einziges Objekt für alle Tasks. In diesem Objekt änderst du die Zahl.
Diese Zahl gibst du in der Schleife aus nachdem der Task erstellt wurde. Da ist er aber noch nicht tatsächlich aktiv.
Was der Task zur Laufzeit tatsächlich ausliest wenn er irgendwann dran kommt, weißt du nicht.

Wenn der Task ausgeführt wird, sieht er den Wert der gerade im Objekt steht. Welcher das ist, hängt davon ab wie weit die Main Methode gerade ist.

Abhilfe: Jedem Task ein eigenes Objekt erstellen, dessen Zahl einmalig gesetzt wird und dann unverändert bleibt.
28.09.2020 07:19 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
witte
myCSharp.de-Mitglied

Dabei seit: 03.09.2010
Beiträge: 936


witte ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Man könnte sich auch mal  Parallel.ForEach anschauen. Weiß aber nicht ob das heute noch uneingeschränkt empfohlen wird (Exception handling). Damit wird das Sync-Problem nicht gelöst sondern man kann sich die Schleifen vereinfachen.
Was hast du eigentlich vor? Willst du ein Objekt speichern dass während der Speicherung sich weiter verändert? Dann solltest du es vllt vorher kopieren.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von witte am 28.09.2020 10:27.

28.09.2020 10:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Die Ursache seines Problems ist ein ganz einer, simpler Architekturfehler.

Es macht überhaupt keinen Sinn hier Workarounds mit paralleler Programmierung zu schaffen, wenn die Ursache eine ganz andere ist und mit simpler asynchroner Programmierung mit 3 Zeilen umzusetzen ist.
Einzige Voraussetzung: er muss den Architekturfehler gerade bügeln.

Aber klar; man kann natürlich auch riesen Code-Konstrukte bauen, die instabil sind, den eigentlichen Zweck nicht erfüllen - hauptsache man muss den eigentlichen Fehler nicht anfassen :-)
28.09.2020 13:52 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Der einzige Fehler ist/war, die Frage wurde im falschen Forum gestellt.

Leider hat mycsharp.de eine toxische Art zu antworten. Insbesondere der im Impressum stehende Abt selbst. Wenn man keinen Bock auf Forum hat, dann sollte man Forum sein lassen.

Es gibt so tolle Foren im Internet wie "Stockoverflow" und viele weitere.

Andererseits hat man da den Eindruck, dass die Mitglieder wirklich helfen wollen, tolle Beispiele und Tipps posten.

Die Leute merken ob jemand eine Berufsprogrammierer oder Hobbyprogrammier ist.
Ob jemand Anfänger oder Profi ist.

Und entsprechend sollten auch die Antworten auffallen.

Wenn jemand keinen Bock hat, etwas zum hundertsten mal zu erklären, dann ist ein Forum einfach der falsche Ansatz. Ein statisches Tutorial wäre vieleicht der bessere Weg gewesen?!?

Natürlich gibt es auch immer Leute die sich bemühen und Antworten, wie chillic, witte oder auch einige andere. Leute die sich wirklich bemühen und auf die Frage eingehen, Lösungen suchen / aufzeigen und kommunizieren.

Leider reagiert Abt nur meistens immer als erstes und dann auf seine unbeschreibliche Art.

Sehr schade für dieses Forum und jetzt bin ich gespannt wie lange der Abt den Post erträgt.
28.09.2020 15:06 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Ich kann mit Kritik gut umgehen, danke der Nachfrage :-)
28.09.2020 15:07 Beiträge des Benutzers | zu Buddylist hinzufügen
T-Virus T-Virus ist männlich
myCSharp.de-Mitglied

Dabei seit: 17.04.2008
Beiträge: 1.698
Entwicklungsumgebung: Visual Studio, Codeblocks, Edi
Herkunft: Nordhausen, Nörten-Hardenberg


T-Virus ist offline Füge T-Virus Deiner Kontaktliste hinzu

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Eine Minute ist neuer Rekord :D
Spaß beiseite.

Abt hat eigentlich genau das gleiche gesagt, wie alle anderen.
Du hast einfach nur einen Fehler im Umgang mit Tasks gemacht und kannst den auch einfach beheben.

Du musst dir mal die Doku anschauen und verstehen was passiert wenn du nebenläufige Verarbeiungen auf einem Objekt laufen lässt.
Du hast dann keine Vorhersagbarkeit welcher Zustand wann eintritt, was hier genau dein Problem ist.

Dies kannst du entweder lösen, wenn du unterschiedliche Objekte hast oder wenn du einfach auf parallele Verarbeitung verzichtest.

Hier wäre es z.B. sinnvoller, wenn du deine Inserts sammelst und durch ein Bulk Insert in einem Rutsch importieren lässt.
Dies spart dir dann auch bei 1.000 Objekten 1.000 Verbindungen und Läufe zwischen dir und der DB.
Gerade für Massenimporte sollte man nie einzelne Inserts laufen lassen sondern gebündelt per Bulk Insert importieren.

T-Virus
28.09.2020 17:25 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 180
Entwicklungsumgebung: Visual Studio 6.0 Enterprise


JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top



Zitat von witte:
Man könnte sich auch mal  Parallel.ForEach anschauen.

Da wird aber auch nicht die richtige Reihenfolge garantiert, und es lohnt sich glaub an erst ab sehr hohen Anzahlen.


Warum wartest du nicht einfach mit await? Warum muss das parallel ablaufen? Vorallem bei den selben Datenbankzugriffen. Oder am Besten mehrere auf einmal wie T-Virus sagt.

Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von JimStark am 29.09.2020 11:08.

29.09.2020 11:06 Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Parallele Verarbeitung vs. Order Preservation sind gegensätzliche Anforderungen.
Das Einhalten einer Order ist extrem kostenintensiv; daher gibt es weder in PLINQ noch in der TPL entsprechende Funktionalitäten, die die Order auf dieser Ebene garantieren oder beachten.
Parallel.ForEach selbst ist nicht sooo teuer.

In PLINQ gibt es mit  AsOrdered die Möglichkeit entsprechende Regeln beizumischen, bei der die Order beachtet wird.
AsOrdered ist dabei jedoch nicht für IO-Operationen gedacht und daher für diesen Anwendungsfall auch nicht geeignet.

await wäre die korrekte Herangehensweise, richtig; aber nicht parallel:
- Datenbank-Verbindungen sind in der Regel nicht Thread-sicher; Du bäruchtest also mehrere Verbindungen
- Da hier offenbar eine Order Preservation notwendig ist, würden ohne selbige Race Conditions entstehen

Im Endeffekt gehts ihm ja auch nur darum, dass Daten gespeichert werden, während er weiterhin an der UI arbeiten kann.
Und dafür reicht ein einziges simples await - wenn der restliche Code passen würde.
29.09.2020 11:15 Beiträge des Benutzers | zu Buddylist hinzufügen
MrSparkle MrSparkle ist männlich
myCSharp.de-Team

avatar-2159.gif


Dabei seit: 16.05.2006
Beiträge: 5.599
Herkunft: Leipzig


MrSparkle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Das Problem ist spätestens mit der zweiten Antwort geklärt. Der OP hat sich bisher komplett geweigert, auf die Fragen zu antworten, die sich ergeben haben, und ist offensichtlich an einer Lösung nicht interessiert.

Wir müssen hier nicht weiter spekulieren, oder diesen Thread mit weiteren Mutmaßungen verlängern.
29.09.2020 15:34 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo an alle,

@ MrSparkle - sorry, hab einiges zu tun und bekomme von euch auch nicht grade wenig und einfache Hausaufgaben. Natürlich bin ich an Lösungen interessiert, nur finde ich weder den Weg noch das Ziel.

Kurz vorab ich bin kein Programmierer oder Entwickler, sondern mache das Ganze als Hobby. Aber ich verstehe oft nicht was ihr schreibt und muss erstmal recherchieren.

Beispiel:

Abt schrieb am 25.09. auf meine Frage:
Im dümmsten Fall eine Race Condition
--> Problem - was ist eine Race Condition???
--> Google + mein Buch Visual C# 2015

Zudem Zeitpunkt hatte ich parallele und asynchron nicht verstanden und fällt mir leider immer noch schwer. Denn es gibt Asynchrone-Programmierung die nicht asynchron ist und Parallele-Programmierung die nicht parallel ist.

Es folgte die Aussage ich soll besser erklären, habe ich versucht.

Im Grunde hätte mir aber als Antwort bereits ausgereicht das B zutrifft.
Die Änderungen am Objekt wirken sich auf den Task aus und umgekehrt.

--> Ergebnis es wird mit dem Task kein neues Objekt erzeugt, sondern das alte durchgereicht.

Wäre bei mir aber kein Problem, weil ich das Objekt eigentlich bis zum nächsten Schleifendurchgang unverändert bleibt. Somit müsste ich nur am Ende der Schleife warten.

Beispiel:

C#-Code:
foreach (var objekt in Objekte)
{
// Mach hier einiges

// Jetzt geändert statt nur TASK.RUN

// erster Prozessor arbeitet weiter im Haupt-Programm
// zweiter Prozessor arbeitet meinen Task ab
var meinTask = Task.Run(() =>  MeinTask(objekt)); // Hier arbeitet der Task mit zweitem Prozessor ohne Objekt zu ändern

…..
….
// Hier macht mein Hauptprogramm sachen ohne das Objekt zu ändern.



// Jetzt ist das Hauptprogramm fertig
// Problem – sollte der Task noch nicht fertig sein (unwahrscheinlich) würde es bei Beginn der Schleife ein neues Objekt werden und somit den bestehenden Task ändern.
// Daher hier eine Pause bis fertig
meinTask.Wait();
}

Die Aussage von Abt vom 25.09 16.48 bringt mich nur bedingt weiter.
asynchrones Problem mit Parallelität zu lösen

--> Ich versteh leider den Unterschied nicht.

Klar Parallelität läuft gleichzeitig zum bestehenden Programm, aber Asynchron doch auch?!?


Natürlich kann ich auch
myThread = new Thread(meinObjekt)
und await machen

Aber dann würde es „meinObjekt“ beim nächsten Schleifendurchlauf doch auch ändern.


Der Hinweis auf einen Artikel mit „Drei-Schichten-Architektur“ brachte mich leider nicht weiter. Man könnte mir auch einen Link zu einem Buch in Amazon schicken. Würde mir genauso helfen. Am besten noch als affiliate link (nur spaß).


Kritik wie die vom Abt vom 28.09.2020 – 13.52 bringt halt nichts.
Was bringt es das Problem genannt zu bekommen, wenn man nach einer Lösung sucht?

Ein einfaches versuch doch:
myThread = new Thread(meinObjekt)

und dort im Thread machst du ein neues meinObjekt und weißt das übergebene zu.
Dann hast du eine Kopie und der Hauptthread änderst sich nicht.


@ T-Virus – danke für deinen Hinweis.
Werde mich bei Gelegenheit mal in Bulk Inserts einarbeiten.
Vermutlich aber nicht notwendig, da das Programm als Service arbeitet und in der Regel weniger als 100 Objekte in der Minute verarbeitet.

@JimStark, es muss nicht Parallel laufen. Im übrigen läuft es nicht Parallel.ForEach, sondern aus einer normalen ForEach-Schleife möchte ich eine weitere Verarbeitung starten (egal ob Thread oder Task).
Ziel ist es meine zwei Prozessoren auszulasten und das Programm zu beschleunigen.
Das müsste aber bei beiden passieren?!?

Problem es gibt keine einfache Beschreibung was der Unterschied zwischen Parallel und Asynchron ist.

Ohne solche Sätze wie:
Parallele Verarbeitung vs. Order Preservation sind gegensätzliche Anforderungen.
Das Einhalten einer Order ist extrem kostenintensiv; daher gibt es weder in PLINQ noch in der TPL entsprechende Funktionalitäten

Man könnte auch japanisch mit mir sprechen, würde ich genau soviel verstehen.

Egal, ich werde weiter lesen, suchen, youtube-Videos schauen und hoffentlich eine Antwort finden.

Bei euch allen möchte ich mich für eure Unterstützung bedanken und auch wenn ich Kritik an Abt ausgesprochen habe, hinsichtlich der für Anfänger weniger geeigneten Antworten, möchte ich mich auch bei Abt bedanken. Nicht zuletzt, dass er hier für das Forum wirklich viel macht und immer schnell Antwortet. Hoffe ich bin mit meiner Frage keinem auf die Füße getreten.

Gruß
ck
30.09.2020 17:31 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 14.495
Herkunft: BW


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Keiner hier kann hellsehen, welchen Wissenstand Du hast.
In technischen Foren ist es aber durchaus üblich mit technischen Begrifflichkeiten zu antworten, die fachlich eben die jeweiligen Bezeichnungen haben.
Solltest Du einen Begriff nicht kennen, was jedem von uns passiert, dann kann man danach eben googlen (gern zuerst) oder eben die Nachfrage stellen; letzteres sehe ich hier im gesamten Thread nicht wirklich.
Du kannst jetzt halt nicht wirklich erwarten, dass wir jede Abkürzung oder jeden Begriff erklären können.

Aber was zB der Unterschied zwischen paralleler Programmierung ist und was die asynchrone Programmierung ist; tausende Male im Netz behandelt.
Dazu gibts auch riesen Topic in den  Microsoft Docs.

Sehr einfach zu merken ist:

Zitat:
use parallel programming for CPU intensive solutions. use asynchronous programming for IO bound solutions.

Du hast eine IO-Anforderung, daher macht hier parallele Programmierung keinen Sinn.
Wurde Dir mehrfach versucht zu vermitteln; Du hast damit halt trotzdem stur weiter gemacht.

Zitat:
Im Grunde hätte mir aber als Antwort bereits ausgereicht das B zutrifft.
Die Änderungen am Objekt wirken sich auf den Task aus und umgekehrt.

Da kann man aber auch antworten: dafür hättest Du keinen Thread gebraucht.
Du hast ja dann doch gesehen, dass Du selbst das ganze mit minimalstem Code selbst beantworten kannst, was im Endeffekt in  [Hinweis] Wie poste ich richtig? steht (und übrigens auch bei StackOverflow unter die Eigeninitiative fällt und meistens daher die Themen sofort geschlossen werden) ;-)

Wenn Du eine Antwort nicht verstehst, dann frag nach. Wenn Du aber wie hier einfach *irgendwas* bastelst, das mit den Hinweisen *absolut* nichts zutun ha oder diese ignorierst, dann macht das keinen Sinn.
Du hast ja ein Thema erstellt um Hinweise und Hilfe zu bekommen. Wenn Du diese dann ignorierst - warum soll man Dir dann antworten..? ;-)

Was aber nun mal das Forum nicht abdeckt (übrigens auch nicht StackOverflow), dass es Dich quasi an der Hand nehmen wird und Dir Stück für Stück alles erklären kann.
Dafür ist das Medium "Forum" und die kostenlose, freiwillige Arbeit von Helfern einfach auch nicht der richtige Adresspunkt.

Bin mir bewusst, dass ich durchaus eine direkte Ausdrucksweise habe - aber letzten Endes antworte ich immer noch um zu helfen. Aber ja, ich kann Kritik durchaus annehmen; teile ja auch aus.
30.09.2020 17:52 Beiträge des Benutzers | zu Buddylist hinzufügen
ck82
myCSharp.de-Mitglied

Dabei seit: 28.09.2015
Beiträge: 32

Themenstarter Thema begonnen von ck82

ck82 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat:
Keiner hier kann hellsehen, welchen Wissenstand Du hast.

// Siehe erster Beitrag
Hallo liebe Pro`s,
hoffe ihr könnt einem Noob etwas unter die Arme greifen.

Zitat:
Solltest Du einen Begriff nicht kennen, was jedem von uns passiert, dann kann man danach eben googlen (gern zuerst)

Künftig werde ich alles Googlen, strengt deutlich weniger an UND bringt leider mehr.

Zitat:
Da kann man aber auch antworten: dafür hättest Du keinen Thread gebraucht.

Sorry, versteh dich einfach nicht

Zitat:
Wenn Du eine Antwort nicht verstehst, dann frag nach.

Was meinst du mit "kann man aber auch antworten"?


Sorry - ich bin raus. Hab keine Lust mehr auf den F... hier.
Normale Diskussion und vernünftige Antworten sind hier leider nicht möglich.

Bitte den Thread schließen.
Kommt leider nichts vernünftiges mehr raus.

Und ich dachte mit meiner Danksagung hätte ich bereits ein versöhnliches Ende gefunden.
30.09.2020 18:38 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
JimStark
myCSharp.de-Mitglied

avatar-1005.jpg


Dabei seit: 10.03.2020
Beiträge: 180
Entwicklungsumgebung: Visual Studio 6.0 Enterprise


JimStark ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Zitat von ck82:
Problem es gibt keine einfache Beschreibung was der Unterschied zwischen Parallel und Asynchron ist.

Ohne solche Sätze wie:
Parallele Verarbeitung vs. Order Preservation sind gegensätzliche Anforderungen.
Das Einhalten einer Order ist extrem kostenintensiv; daher gibt es weder in PLINQ noch in der TPL entsprechende Funktionalitäten

Asynchron --> man macht weiter ohne zu warten
Parallel --> es läuft zur selben Zeit ab

Bei deinem Fall macht das parallele arbeiten absolut keinen Sinn, das könntest du z.B. machen wenn du Arrays mit Pixeln hast und die mittels Interpolation skalieren willst. --> hohe Rechenpower notwendig, kann nebeneinander laufen, nicht abhängig,...
Bei einer Datenbankabfrage macht es halt gar keinen Sinn, das wird auch nicht schneller. Und du lastest damit deine CPU-Kerne auch nicht aus großes Grinsen Alles wie oben schon mehrfach erwähnt.

Bei dir bietet es sich an asynchron zu machen, dass die GUI oder was auch immer nicht hängen bleibt. Was jetzt genau dein Problem damit ist, verstehe ich aber immer noch nicht.

Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von JimStark am 30.09.2020 20:37.

30.09.2020 20:35 Beiträge des Benutzers | zu Buddylist hinzufügen
myCSharp.de
Moderationshinweis von Abt (30.09.2020 21:20):

Wie gewünscht. Alles Gute und viel Erfolg.
 
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 4 Monate.
Der letzte Beitrag ist älter als 3 Monate.
geschlossen (weitere Infos)


© Copyright 2003-2021 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 25.01.2021 13:37