Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C# / VB.NET - [C#]Multi thread e timer
Forum - C# / VB.NET - [C#]Multi thread e timer

Avatar
Roby94 (Member)
Guru


Messaggi: 1127
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 19:02
Martedì, 08/04/2014
Salve, avrei un dubbio sulla gestione multi thread, dentro un mio programma ho due timer con un tempo di cadenza di 100ms e 500ms, nonostante io non abbia mai studiato a fondo la classe timer immagino che implementi al suo interno già un sistema di multi thread che eviti che si ostacolino a vicenda, quindi la mia prima domanda è posso fidarmi di questo o serve un mio intervento manuale al codice?
Vorrei aggiungere inoltre un sistema di animazione che al variare di una proprietà del viewmodel modifica la dimensione del form con un animazione. Volevo implementare l'animazione ridimensionando la finestra di un piccolo Δw addormentare il thread principale e ripetere l'operazione come si fa in JS. Mi pare però una pratica un po barbara, e la cosa che più mi spaventa è se questo processo blocchi/rallenti i timer, sono paure fondate? Perché?
e in ultimo sicuramente esiste un metodo migliore per creare un animazione del genere, me lo sapete consigliare?

Grazie in anticipo


La programmazione è arte... fa che i tuoi script siano degni di un museo.
PM Quote
Avatar
R0gerBlack (Member)
Expert


Messaggi: 210
Iscritto: 10/06/2010

Segnala al moderatore
Postato alle 21:09
Martedì, 08/04/2014
Che io sappia, dal momento che i Timer lavorano in background come thread separati non hanno latenze (e in un certo senso non c'è una certezza matematica se ogni mezzo secondo verrà eseguito leggermente prima il prmo o il secondo). Se hai messo 100 ms il timer verrà eseguito ogni 100 ms. Tuttavia non ho capito esattamente cosa vuoi.

Hai 2 timer, uno da 100 ms e uno da 500 ms. Il sistema di animazione dove viene eseguito e in cosa consiste esattamente?


Volere è potere.

Se la conoscenza crea problemi, non è con l'ignoranza che si risolvono [Isaac Asimov]
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1127
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 21:23
Martedì, 08/04/2014
La precisione millesima non la cerco e non la pretendo, il mio dubbio (visto che non conosco bene il modo in cui lavora la classe) era se si ostacolassero a vicenda, un dubbio che mi sembrava remoto ma preferivo una certezza :)
Allora l'animazione deve essere effettuata sul thread principale da parte del form. L'animazione si verificherà al momento del set di una proprietà, questa animazione consisterà nel ridimensionamento della window solo sull'asse orizzontale, e sarà la classica animazione "Sliding" (es http://api.jquery.com/slideToggle/)
Pensavo di farla con un ciclo for tipo
Codice sorgente - presumibilmente Plain Text

  1. for(i=0;i<x;i++) {
  2.     w++;
  3.     thread.sleep(2);
  4. }


mi sembra un metodo abbastanza squallido, visto che addormento il thread, chiedevo se ci fossero alternative più eleganti...

Grazie :)


La programmazione è arte... fa che i tuoi script siano degni di un museo.
PM Quote
Avatar
R0gerBlack (Member)
Expert


Messaggi: 210
Iscritto: 10/06/2010

Segnala al moderatore
Postato alle 21:58
Martedì, 08/04/2014
Testo quotato

Postato originariamente da Roby94:
Allora l'animazione deve essere effettuata sul thread principale da parte del form. L'animazione si verificherà al momento del set di una proprietà, questa animazione consisterà nel ridimensionamento della window solo sull'asse orizzontale, e sarà la classica animazione "Sliding"



Se ho capito bene vuoi eseguire l'animazione nel thread principale con l'istruzione System.Threading.Thread.Sleep(int n);. Sinceramente te lo sconsiglio, ma dipende da quello che vuoi fare.
Oltre a motivi di eleganza, l'istruzione Thread Sleep ti blocca il programma finché il for non è finito.

Ti consiglierei di aprire un thread a parte, senza uso di timer.
Nota: Qualche programmatore potrebbe obiettare sull'eleganza di questo metodo ma sembra essere per il caso tuo

Codice sorgente - presumibilmente C# / VB.NET

  1. using System.Threading;


Codice sorgente - presumibilmente C++

  1. Thread td1;
  2. private void Form1_Load(object sender, EventArgs e)
  3. {
  4.         // Quest'istruzione serve per permettere il cross threading
  5.         Button.CheckForIllegalCrossThreadCalls = false;
  6.         td1 = new Thread(new ThreadStart(StartAnimation));
  7. }
  8.  
  9. private void button1_Click(object sender, EventArgs e)
  10. {
  11.  
  12.         td1.Start();
  13. }
  14.  
  15. private void StartAnimation()
  16. {
  17.         for (int i = 0; i < 300; i++)
  18.         {
  19.                 button1.Location = new Point(button1.Location.X + 1, button1.Location.Y);
  20.                 Thread.Sleep(3);
  21.         }
  22.        
  23.         // Se vuoi rieseguire l'animazione in futuro
  24.         // Abilita questo codice
  25.         // td1 = new Thread(new ThreadStart(StartAnimation));
  26. }



Ho utilizzato un button perché non mi è chiaro il genere di animazione che vuoi eseguire, comunque basta adattarla a questo algoritmo.

Se provi a eseguire il tuo metodo, noterai che durante l'animazione non potrai fare nulla, nemmeno muovere il form.
Con questo metodo, l'animazione avviene in maniera asincrona.
In questo esempio nel for decido la quantità di pixel da scorrere in orizzontale e la latenza dell'animazione.
Non mi sembra comunque una brutta idea considerando che il programma non si tratta di un gioco (che invece in genere usa motori grafici avanzati).

Dimmi che te ne pare.

Ultima modifica effettuata da R0gerBlack il 08/04/2014 alle 22:11


Volere è potere.

Se la conoscenza crea problemi, non è con l'ignoranza che si risolvono [Isaac Asimov]
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1127
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 23:47
Martedì, 08/04/2014
Grazie :) allora il fatto che la window si fermasse per l'esecuzione dell'animazione non è un problema e mi sembra anche più sicura come cosa... Vorrei solo vedere se troviamo una soluzione meno da molestia al thread :)

Edit:
Ho notato che il metodo RaisePropertyChanged impediva un approccio del tipo esposto sopra poiche troppo lenta...
Sono passato ad un animazione fatta da XAML
Codice sorgente - presumibilmente Plain Text

  1. <RadioButton Content="Manuale" IsChecked="{Binding ManualMode}" Style="{StaticResource RadioButtonMode}">
  2.                     <RadioButton.Triggers>
  3.                         <EventTrigger RoutedEvent="RadioButton.Checked">
  4.                             <BeginStoryboard>
  5.                                 <Storyboard>
  6.                                     <DoubleAnimation
  7.                                         Storyboard.TargetName="Window"
  8.                                         Storyboard.TargetProperty="Width"
  9.                                         To="320" Duration="0:0:0.3"/>
  10.                                 </Storyboard>
  11.                             </BeginStoryboard>
  12.                         </EventTrigger>
  13.                     </RadioButton.Triggers>
  14.                 </RadioButton>



Grazie mille per gli aiuti :)

Ultima modifica effettuata da Roby94 il 09/04/2014 alle 22:15


La programmazione è arte... fa che i tuoi script siano degni di un museo.
PM Quote
Avatar
vankraster (Member)
Rookie


Messaggi: 32
Iscritto: 05/11/2010

Segnala al moderatore
Postato alle 13:16
Giovedì, 10/04/2014
Scusate che mi intrometto,
@Roby94 ma i timer che stai utilizzando sono dei System.Timers.Timer oppure System.Windows.Forms.Timer ?
Ci sarebbe anche il terzo System.Threading.Timer ma non penso facci al tuo caso nonostante sia sotto system.threading, io ti suggerisco di usare il primo migliore e anche più preciso.


Ci possono togliere tutto tranne la ragione e con questa possiamo ricostruire l'universo.
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1127
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 14:07
Giovedì, 10/04/2014
Solo ed esclusivamente System.Timers; ;)
Lo uso per le connessioni e le animazioni le effettuo direttamente in XAML


La programmazione è arte... fa che i tuoi script siano degni di un museo.
PM Quote