| |
 | Online-Kurs: Grundlagen des 3D-Druck-Designs für Industrieingenieure , ein Kurs
|
Autor
|
Thema: Problem mit Threads (6440 mal gelesen)
|
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 20. Mai. 2005 08:48 <-- editieren / zitieren --> Unities abgeben:         
Hi ! Ich möchte in einer Funktion einen bestimmten Teil timergesteuert ablaufen lassen. zB. eine sec. irgendwas aufaddieren. Aber wenn ich den WindowsFormTimer mit den Werten aus meiner Funktion arbeiten lassen möchte, sind die Variablen aus meiner Funktion im Timer nicht bekannt. Habe gehört, das es mit Threads funktionieren soll, weil die ja die bis dato angelegten Variablen erben. Weiß eventuell jemand wie das funktioniert ? Gruß Robin Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
Andreas2DEasy Mitglied Softwareentwickler

 Beiträge: 73 Registriert: 29.12.2004
|
erstellt am: 20. Mai. 2005 10:03 <-- editieren / zitieren --> Unities abgeben:          Nur für _InvasoR_
hallo, es grundsätzlich auch mit einem timer.wichtig dabei sit egal ob mit timer oder thread das wenn du mit variblen arbeiten möchtest im gleichen Namensraum arbeiten musst. du kannst aber den Timer z.B auch dynamisch programmieren.mache doch einfach folgendes: deklariere in deiner Funktion einen timer, deklariere in deiner funktion eine weitere funktion(z.B addiere ) diese weist du dann dem Timer -Ereignis zu und startest dann an entsprecheneder Stelle.nach beendigung der Funktion wird dann auch dein Timerobjekt freigegeben. mit einem thread geht es genauso. Gruß Andreas ------------------ Nobody is perfect Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 20. Mai. 2005 11:36 <-- editieren / zitieren --> Unities abgeben:         
|
FlorianGerteisz Mitglied IT-Anwendungsentwickler

 Beiträge: 43 Registriert: 28.04.2005
|
erstellt am: 23. Mai. 2005 09:34 <-- editieren / zitieren --> Unities abgeben:          Nur für _InvasoR_
Hallo Robin, eine recht triviale Lösung, wäre einfach deine Werte in Member-Variablen zu speichern. Code:
using System; using System.Threading;namespace SWXSpielwiese { public class TolleKlasse { private int a; private int b; private int erg; public void GenialeFunktion(int wert1, int wert2) { this.a = wert1; this.b = wert2; } public void Addiere() { this.erg = this.a + this.b; } } } ... [irgendwo anders] TolleKlasse tk = new TolleKlasse(); tk.GenialeFunktion(2,5); new Thread (new ThreadStart (tk.Addiere)).Start(); ...
Ein paar schönere Lösungen gibt es hier: http://www.yoda.arachsys.com/csharp/threadstart.html Hilft dir das weiter? gruß flo ------------------ [Diese Nachricht wurde von FlorianGerteisz am 23. Mai. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 24. Mai. 2005 11:54 <-- editieren / zitieren --> Unities abgeben:         
Vielen Dank Florian. So was ähnliches hab ich schon probiert aber irgendwas mach ich noch falsch. Ich möchte in SldWorks mit drag operator dinge bewegen und die Bewegung soll in nem eigenen Thread laufen( in angegebener Zeit eine bestummte Strecke zurück legen )... Ich probier jetzt mal noch n bischen an meinem Zeug rum und wenn das nichts bringt veruch ichs mal so wie Du es vorgeschlagen hast. Und nochmal Danke  Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FlorianGerteisz Mitglied IT-Anwendungsentwickler

 Beiträge: 43 Registriert: 28.04.2005
|
erstellt am: 24. Mai. 2005 12:43 <-- editieren / zitieren --> Unities abgeben:          Nur für _InvasoR_
|
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 24. Mai. 2005 13:10 <-- editieren / zitieren --> Unities abgeben:         
private void StreckenThread_Click(object sender, System.EventArgs e) { SldWorks.ModelDoc2 Model = swApp.IActiveDoc2; SldWorks.AssemblyDoc Assembly = (SldWorks.AssemblyDoc) Model; SldWorks.DragOperator DragOp = (SldWorks.DragOperator) Assembly.GetDragOperator(); SldWorks.SelectionMgr SelMgr = (SldWorks.SelectionMgr) Model.SelectionManager; SldWorks.Component2 Comp = null; Comp = SelMgr.IGetSelectedObjectsComponent2(1); SldWorks.MathUtility MathUtil = (SldWorks.MathUtility) swApp.GetMathUtility(); SldWorks.MathTransform Xform = null; int Strecke = 100; double [] MATRIX = new double [16]; // Rotation MATRIX [0] = 1; MATRIX [1] = 0; MATRIX [2] = 0; MATRIX [3] = 0; MATRIX [4] = 1; MATRIX [5] = 0; MATRIX [6] = 0; MATRIX [7] = 0; MATRIX [8] = 1; // Transform MATRIX [9] = 0; MATRIX [10] = 0; MATRIX [11] = 0; // Skalierung MATRIX [12] = 1; // unused MATRIX [13] = 0; MATRIX [14] = 0; MATRIX [15] = 0; //double [] TempMatrix ={1,0,0,0,1,0,0,0,1,0,0,0,1,0,0,0}; System.Array Data = MATRIX; DragOp.CollisionDetectionEnabled = false; DragOp.DynamicClearanceEnabled = false; DragOp.TransformType = 2; TimerState2 s = new TimerState2(Model, Assembly,DragOp, SelMgr, Comp, MathUtil, Xform, MATRIX, Data, Strecke); TimerCallback timerDelegate = new TimerCallback(ChangeValues); s.Model = Model; s.Assembly = Assembly; s.DragOp = DragOp; s.SelMgr = SelMgr; s.Comp = Comp; s.MathUtil = MathUtil; s.Xform = Xform; s.MATRIX = MATRIX; s.Data = Data; s.Strecke = Strecke; System.Threading.Timer timer = new System.Threading.Timer(timerDelegate, s, 0, 1000); s.tmr = timer; while(s.tmr != null) Thread.Sleep(1000); }
class TimerState2 { public SldWorks.ModelDoc2 Model = null; public SldWorks.AssemblyDoc Assembly = null; public SldWorks.DragOperator DragOp = null; public SldWorks.SelectionMgr SelMgr = null; public SldWorks.Component2 Comp = null; public SldWorks.MathUtility MathUtil = null; public SldWorks.MathTransform Xform = null; public double [] MATRIX = new double [16]; public System.Array Data = null; public int Strecke = 100; public System.Threading.Timer tmr; public TimerState2( SldWorks.ModelDoc2 Model, SldWorks.AssemblyDoc Assembly, SldWorks.DragOperator DragOp, SldWorks.SelectionMgr SelMgr, SldWorks.Component2 Comp, SldWorks.MathUtility MathUtil, SldWorks.MathTransform Xform, double [] MATRIX, System.Array Data, int Strecke ) { this.Model = Model; this.Assembly = Assembly; this.DragOp = DragOp; this.SelMgr = SelMgr; this.Comp = Comp; this.MathUtil = MathUtil; this.Xform = Xform; this.MATRIX = MATRIX; this.Data = Data; this.Strecke = Strecke; } } static void ChangeValues(Object state) { TimerState2 s =(TimerState2) state; s.Strecke --; //MessageBox.Show(s.Comp.Name.ToString()); vorher schon abschiss s.MATRIX [9] = 0.01 / 100; // ( MaxIterations ) s.MATRIX [10] = 0.01 / 100; s.MATRIX [11] = 0.01 / 100; s.Xform = (SldWorks.MathTransform) s.MathUtil.CreateTransform( s.Data ); s.DragOp.Drag(s.Xform); if( s.Strecke <= 0 ) { s.tmr.Dispose(); s.tmr = null; } } Es ist leider n bischen viel und auch bestimmt viel schrott dabei...  Gruß Robin Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 24. Mai. 2005 13:16 <-- editieren / zitieren --> Unities abgeben:         
und das Beispiel nach dem ich meinen Code angepasst habe ist dieser hier. Ist eventuell etwas übersichtlicher  using System; using System.Threading;
namespace timertest { class TimerExampleState { public int zahl = 0; public int counter = 0; public Timer tmr; //public TimerExampleState(){} public TimerExampleState( int zahl) { this.zahl = zahl; this.counter = 0; } } class Class1 { public static void Main() { //TimerExampleState s = new TimerExampleState(); TimerExampleState s = new TimerExampleState(5); // Create the delegate that invokes methods for the timer. TimerCallback timerDelegate = new TimerCallback(CheckStatus); // Create a timer that waits one second, then invokes every second. Timer timer = new Timer(timerDelegate, s, 0, 1000); // Keep a handle to the timer, so it can be disposed. s.tmr = timer; Console.WriteLine(s.zahl); // The main thread does nothing until the timer is disposed. while(s.tmr != null) Thread.Sleep(0); Console.WriteLine("Timer example done."); Console.WriteLine(s.zahl); Console.ReadLine(); } // The following method is called by the timer's delegate. static void CheckStatus(Object state) { TimerExampleState s =(TimerExampleState) state; s.counter++; Console.WriteLine("{0} Checking Status {1}.",DateTime.Now.TimeOfDay, s.counter); s.zahl = 9; // Wert geändert if(s.counter == 5) { // Shorten the period. Wait 10 seconds to restart the timer. (s.tmr).Change(1000,100); Console.WriteLine("changed..."); } if(s.counter == 10) { Console.WriteLine("disposing of timer..."); s.tmr.Dispose(); s.tmr = null; } } } }
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FlorianGerteisz Mitglied IT-Anwendungsentwickler

 Beiträge: 43 Registriert: 28.04.2005
|
erstellt am: 24. Mai. 2005 13:45 <-- editieren / zitieren --> Unities abgeben:          Nur für _InvasoR_
Wenn ich dich richtig verstanden habe, willst du doch "nur" nach einem Klick auf einen Button, deine "Animation" ablaufen lassen, oder?! Muss dazu das Programm weiter bedienbar bleiben (dann wäre ein Thread nötig!) oder erst wieder nach der "Animation"? Falls 2. der Fall ist, wäre die Lösung einfach (in meinem jugendlichen Leitsinn daher gesagt *g*):
Code:
while(Strecke > 0) { ChangeValues(); Thread.Sleep(1000); }
Vielleicht habe ich das Problem aber auch nicht ganz verstanden?! gruß flo PS: Du verwendest in deinem Code keinen wirklichen Thread, sondern nur den Timer aus der Thread-Klasse. Hier ist ein guter Artikel über Threads in C# http://www.devtrain.de/artikel_790.aspx ------------------ Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 24. Mai. 2005 16:58 <-- editieren / zitieren --> Unities abgeben:         
Ob es in der Zeit bedienbar sein kann oder nicht ist nicht so wichtig. mein Cheff meinte es müsste mit einem Thread zu machen sein, in einer Funktion Code auszuführen der mit Daten von einer anderen Stelle arbeitet und diese verändert. und das mit einem Timer. Aber wenn ich zB den Windows Timer benutze und Zugriff auf meine SldWorks Daten haben möchte bekomm ich das ohne Weiteres auch nicht hin  ich kann irgendie dem EventHandler nicht so viele Daten mit geben ... hab auch schon wieder was neues probiert was ähnlich ist wie das von vorhin es funktioniert auch bis an eine stelle ... und zwar wenn diese Zeile ausgeführt wird. s.Xform = (SldWorks.MathTransform) s.MathUtil.CreateTransform( s.Data ); ich habe alles mögliche probiert aber die zuweisung mag er irgendwie nicht  __________________________________CODE________________________________ class MovePerTimer { public int zaehler; public System.Threading.Timer timer; SldWorks.SldWorksClass swApp; public SldWorks.ModelDoc2 Model = null; public SldWorks.AssemblyDoc Assembly = null; public SldWorks.DragOperator DragOp = null; public SldWorks.SelectionMgr SelMgr = null; public SldWorks.Component2 Comp = null; public SldWorks.MathUtility MathUtil = null; public SldWorks.MathTransform Xform = null; public double [] MATRIX = new double [16]; public System.Array Data = null; public int Strecke = 100; public MovePerTimer (SldWorks.SldWorksClass swApp) // KONSTRUKTOR { this.Model = swApp.IActiveDoc2; this.Assembly = (SldWorks.AssemblyDoc) this.Model; this.DragOp = (SldWorks.DragOperator) this.Assembly.GetDragOperator(); this.SelMgr = (SldWorks.SelectionMgr) this.Model.SelectionManager; this.Comp = this.SelMgr.IGetSelectedObjectsComponent2(1); this.MathUtil = (SldWorks.MathUtility) swApp.GetMathUtility(); //this.Xform = (SldWorks.MathTransform) this.MathUtil.CreateTransform(this.Data); this.MATRIX [0] = 1; this.MATRIX [1] = 0; this.MATRIX [2] = 0; this.MATRIX [3] = 0; this.MATRIX [4] = 1; this.MATRIX [5] = 0; this.MATRIX [6] = 0; this.MATRIX [7] = 0; this.MATRIX [8] = 1; // Transform this.MATRIX [9] = 0; this.MATRIX [10] = 0; this.MATRIX [11] = 0; // Skalierung this.MATRIX [12] = 1; // unused this.MATRIX [13] = 0; this.MATRIX [14] = 0; this.MATRIX [15] = 0; this.Data = this.MATRIX; } } static void CheckStatusNeu(Object state) { MovePerTimer s = (MovePerTimer) state; s.Strecke --; s.MATRIX [9] = 0.001; //0.01 / 100; // ( MaxIterations ) s.MATRIX [10] = 0.001; //0.01 / 100; s.MATRIX [11] = 0.001; //0.01 / 100; s.Data = s.MATRIX; // Zeile neu hinzu gefügt s.Xform = (SldWorks.MathTransform) s.MathUtil.CreateTransform( s.Data ); // an dieser stelle kackt immer Programm ab /// KA warum  s.DragOp.Drag(s.Xform); if( s.Strecke <= 0 ) { s.timer.Dispose(); s.timer = null; } } private void TimeThread_Click(object sender, System.EventArgs e) { SldWorks.ModelDoc2 Model = swApp.IActiveDoc2; SldWorks.AssemblyDoc Assembly = (SldWorks.AssemblyDoc) Model; SldWorks.DragOperator DragOp = (SldWorks.DragOperator) Assembly.GetDragOperator(); SldWorks.SelectionMgr SelMgr = (SldWorks.SelectionMgr) Model.SelectionManager; SldWorks.Component2 Comp = null; Comp = SelMgr.IGetSelectedObjectsComponent2(1); SldWorks.MathUtility MathUtil = (SldWorks.MathUtility) swApp.GetMathUtility(); SldWorks.MathTransform Xform = null; int Strecke = 100; DragOp.AddComponent(Comp, true); DragOp.BeginDrag(); MovePerTimer OBJEKT = new MovePerTimer(swApp); TimerCallback timerDelegate = new TimerCallback(CheckStatusNeu); System.Threading.Timer timer = new System.Threading.Timer( timerDelegate, OBJEKT, 1000, 1000 ); OBJEKT.timer = timer; while(OBJEKT.timer != null) Thread.Sleep(0); } ____________________________________CODE ENDE_________________________ Gruß Robin P.S. Florian, wie machst du diese tollen Codeblöcke ? Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FlorianGerteisz Mitglied IT-Anwendungsentwickler

 Beiträge: 43 Registriert: 28.04.2005
|
erstellt am: 25. Mai. 2005 08:23 <-- editieren / zitieren --> Unities abgeben:          Nur für _InvasoR_
Zitat: hab auch schon wieder was neues probiert was ähnlich ist wie das von vorhin es funktioniert auch bis an eine stelle ... und zwar wenn diese Zeile ausgeführt wird. s.Xform = (SldWorks.MathTransform) s.MathUtil.CreateTransform( s.Data ); ich habe alles mögliche probiert aber die zuweisung mag er irgendwie nicht
Wäre auch schlecht, wenn es funktionieren würde -> auskommentiert :-) Code: //this.Xform = (SldWorks.MathTransform) this.MathUtil.CreateTransform(this.Data);
Zum Thema Thread nochmal: Ein solcher wird (meistens) dazu verwendet Vorgänge parallel Ablaufen zu lassen. Das sehe ich bei deiner Aufgabenstellung aber irgendwie nicht!?! Du möchtest doch nur zwei Dinge nacheinander in einer Schleife abarbeiten: 1.Daten ändern (für die Transformation) 2.Die eigentliche Transformation Ist das so? gruß flo ------------------ [Diese Nachricht wurde von FlorianGerteisz am 25. Mai. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 25. Mai. 2005 12:59 <-- editieren / zitieren --> Unities abgeben:         
Zitat:Wäre auch schlecht, wenn es funktionieren würde -> auskommentiert :-)
Code: //this.Xform = (SldWorks.MathTransform) this.MathUtil.CreateTransform(this.Data);
Hab alles Mögliche ausprobiert und beim Beispiel posten vergessen das Kommentar raus zu nehmen Es geht aber auch nicht wenn die Zeile nicht auskommentiert ist.
Was ich noch komisch finde. Ich habe die ganzen Blöcke mit try - catch anweisungen versehen. Aber es kommt keine Exception wenn die Anwendung abschmiert. Es kommt nur "keine Rückmeldung"... Zitat:
Du möchtest doch nur zwei Dinge nacheinander in einer Schleife abarbeiten: 1.Daten ändern (für die Transformation) 2.Die eigentliche Transformation Ist das so?
Ja genau das möcht ich. Das Ganze muss nur in einer bestimmten Zeit ablaufen. Also wenn ich zB. 1 Sec vorgebe und der Timertick alle 100 Millisekunden ist, soll die Bewegung bei jedem Tick ein Zehntel der Strecke betragen. Gruß Robin [Diese Nachricht wurde von _InvasoR_ am 25. Mai. 2005 editiert.] Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |
FlorianGerteisz Mitglied IT-Anwendungsentwickler

 Beiträge: 43 Registriert: 28.04.2005
|
erstellt am: 08. Jun. 2005 09:52 <-- editieren / zitieren --> Unities abgeben:          Nur für _InvasoR_
|

| |
_InvasoR_ Mitglied student

 Beiträge: 55 Registriert: 17.03.2005
|
erstellt am: 08. Jun. 2005 20:14 <-- editieren / zitieren --> Unities abgeben:         
Hi Flo, Ja mittlerweile hab ich ne lösung dafür. ich habs nicht mit nem timethread gelöst, sondern mit nem normalen WindowsFormTimer und dann mit nem ZusatzEvent den ich über den Tick EventHandler mit auslöse. Kann dir aber auch wenn Du möchtest Morgen meine Lösung posten. Gruß Robin
Eine Antwort auf diesen Beitrag verfassen (mit Zitat/Zitat des Beitrags) IP |