![]() |
Zugriff zwischen zwei Threads
Hallo!
Da ich mich mit Threads nicht auskenne, habe ich zwei simple Fragen: Ich habe einen Thread in dem nur eine Schleife läuft. 1. Wie kann ich aus diesem Thread herraus eine Komponente des Formulars (das ja logischerweise in einem anderen Thread - im Hauptthread läuft) aufrufen? 2. Beendet sich der Thread automatisch nach ablauf der Schleife, oder muss ich das selbst machen? Danke schon mal für jede Antwort Grüße Faux |
Re: Zugriff zwischen zwei Threads
Zu 2.: Ja, der Thread beendet sich. Allerdings weiß ich nicht, dazu befragst du am besten die Doku, ob das Thread-Objekt (also der .NET-Wrapper) auch freigegeben wird.
Einen Zugriff sollte man immer synchronisieren. Wei du das in .NET machst, ist mir allerdings unbekannt. Außerdem wäre da noch da Problem, daß die eigentlichen drunterliegenden APIs nicht alle threadsafe sind. Ob es die angebotenen Objekte also sind, ist noch eine andere Frage. |
Re: Zugriff zwischen zwei Threads
Danke für die Antwort!
Wie könnte ich ansonsten das folgende Problem lösen: Ich berechne in einer FOR-Schleife, die in einem eigenständigen Thread läuft, pro Durchlauf einen String. Nach jedem Durchlauf soll dieser String dann in eine Komponente (listView) geschrieben werden. Auf die Komponente kann ich aber nicht einfach so zugreifen, da diese ja in einem seperaten Thread läuft... Bin für jeden Vorschlag dankbar. Grüße Faux |
Re: Zugriff zwischen zwei Threads
Zitat:
|
Re: Zugriff zwischen zwei Threads
Kann man den Thread eigentlich Pausieren?
|
Re: Zugriff zwischen zwei Threads
Sollte gehen, aber was soll das bringen? Im Gegensatz zu Fibers ist das nicht sonderlich gut steuerbar. Am sichersten ist es, wenn sich ein Thread selber schlafenlegt.
Stichwort: Suspend |
Re: Zugriff zwischen zwei Threads
Zitat:
|
Re: Zugriff zwischen zwei Threads
Zitat:
|
Re: Zugriff zwischen zwei Threads
Ja, das ist schon richtig so, nur wie würdest du das lösen?
Ich würde eine Globale Variable haben, in die der Thread seinen String schreibt. Der Overhead Nimmt dann den String und macht was damit, dann wird der String wieder gelöscht. Der Thread wartet enzwischen auf das Löschen des Strings und fährt dann fort. NUR: Wie weißt der Overhead, dass der String jetzt bereit ist? Dan müsste ich ja erst wieder im Overhead ne Schleife laufen lassen, oder? Kann sein, dass du das jetzt GANZ anders meinst... ;) Bitte nen mal kurz ein Bsp, wenn das so ist... Grüße Faux |
Re: Zugriff zwischen zwei Threads
Zitat:
|
Re: Zugriff zwischen zwei Threads
Ups... ;)
Ich dachte, das ist der "Grundprozess", ich weiß nicht, wie man da sonst sagt... :oops: |
Re: Zugriff zwischen zwei Threads
Auch Prozess ist der falsche Ausdruck. Ein Prozess ist nur ein Container, der den Adressraum usw. für den (Haupt)Thread bereitstellt, der den eigentlichen Code ausführt. Ein Prozess selber führt nie Code aus. Letztendlich läuft es auf einen Handshake hinaus: Der eine Thread sagt dem anderen immer wann er fertig ist und der andere Thread was machen kann. Es geht also immer hin und her wie beim Ping Pong. Dazu hast du drei Threads: den Hauptthread, der die beiden Threads anstößt und die beiden Workerthreads, die letztendlich die Arbeit machen.
Zum Benachrichtigen kann man dann Events nutzen, die sollte es unter .NET auch noch geben oder zu mindes was vergleichbares. |
Re: Zugriff zwischen zwei Threads
Zitat:
|
Re: Zugriff zwischen zwei Threads
Sollte, zu mindest geht es unter WinAPI.
|
Re: Zugriff zwischen zwei Threads
Zitat:
|
Re: Zugriff zwischen zwei Threads
Du kannst von ThreadX ein Control in seinem Thread ansprechen in dem du einen Delegate an seine Invoke methode schickst.
Um thread safety zu wahren gibt es die Monitor klasse (siehe SDK Doku) oder critical sections:
Code:
Im allgemein kannst du auch statische Properties als thread safe ansehen solange du in den Accessors nix machst, dass nicht thread safe ist.
lock(someObject)
{ Statement(someObject); someObject.DoSomething(); } |
Re: Zugriff zwischen zwei Threads
Wenn ich DAS mach:
Code:
Ist das 1. Zulässig 2. Schön (also gibts ne bessere Möglichkeit) 3. die Form noch Benutzbar, wärend der Thread läuft?
lock(typeof(Form1))
{ Form1.textBox1.Text = Irgendwas; } |
Re: Zugriff zwischen zwei Threads
Hi,
zulässig ist es, die Form ist auch weiter benutzbar, allerdings ist es so nicht dazu geeignet, um auf ein Control zuzugreifen. Ein Zugriff auf ein Control muss immer aus dem Thread erfolgen, der das Control angelegt hat, also (so gut wie immer) aus dem Hauptthread der Anwendung. Das kannst du, wie Robert schon geschrieben hat, erreichen, in dem du die Methode die auf das Control zugreift über Invoke aufrufst. Beispiel:
Code:
Das Problem dabei ist, dass der Invoke-Aufruf so lange nicht zurückkehrt bis die übergebene Methode im Hauptthread ausgeführt worden ist und der Thread somit auch nicht weiterarbeiten kann. Sollte das stören, musst du die Daten in einen Zwischenpuffer schreiben (Array oder ähnliches) den Zugriff darauf synchronisieren (manche Collections gibt's schon als Thread-sichere Variante) und dir eine Möglichkeit überlegen, wie du dem Hauptthread mitteilst, dass neue Daten im Puffer sind.
public class MyThread
{ public delegate void UpdateDelegate(string s); public TextBox StatusTB; void Update(string s) { StatusTB.Text = s; } void Execute() // Thread-Routine { // ... StatusTB.Invoke(new UpdateDelegate(Update), new object[] {"foo"}); // ... } // ... } Zu lock: Das kannst du verwenden, wenn du auf Felder aus verschiedenen Threads heraus zugreifen willst, und verhindern möchtest, dass sie sich dabei in die Quere kommen. Beispiel:
Code:
Wenn jetzt einer der Threads zum Beispiel set Datum ausführt, wird bei Lock(this) geprüft, ob bereits ein anderer Thread ein lock auf das Objekt ausgeführt hat. Ist das der Fall, dann wartet der neue Thread, bis der andere Thread den kritischen Abschnitt verlassen hat und fährt erst dann fort.
public class GemeinsameDaten
{ private object dat; public object Datum { set { lock(this) { dat = value; } } get { object d; lock(this) { d = dat; } return d; } } |
Re: Zugriff zwischen zwei Threads
Für asynchrone Aufrufe zwischen den Threads gibt es noch BeginInvoke anstelle des einfachen Invoke.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz