Oppure

Loading
08/04/14 17:02
Roby94
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
aaa
08/04/14 19:09
R0gerBlack
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?
aaa
08/04/14 19:23
Roby94
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 api.jquery.com/slideToggle/)
Pensavo di farla con un ciclo for tipo
for(i=0;i<x;i++) {
    w++;
    thread.sleep(2);
}

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

Grazie :)
aaa
08/04/14 19:58
R0gerBlack
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

using System.Threading;

Thread td1;
private void Form1_Load(object sender, EventArgs e)
{
        // Quest'istruzione serve per permettere il cross threading
        Button.CheckForIllegalCrossThreadCalls = false;
        td1 = new Thread(new ThreadStart(StartAnimation));
}

private void button1_Click(object sender, EventArgs e)
{

        td1.Start();
}

private void StartAnimation()
{
        for (int i = 0; i < 300; i++)
        {
                button1.Location = new Point(button1.Location.X + 1, button1.Location.Y);
                Thread.Sleep(3);
        }
        
        // Se vuoi rieseguire l'animazione in futuro
        // Abilita questo codice
        // td1 = new Thread(new ThreadStart(StartAnimation));
}


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 08/04/14 20:11
aaa
08/04/14 21:47
Roby94
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
<RadioButton Content="Manuale" IsChecked="{Binding ManualMode}" Style="{StaticResource RadioButtonMode}">
                    <RadioButton.Triggers>
                        <EventTrigger RoutedEvent="RadioButton.Checked">
                            <BeginStoryboard>
                                <Storyboard>
                                    <DoubleAnimation
                                        Storyboard.TargetName="Window"
                                        Storyboard.TargetProperty="Width"
                                        To="320" Duration="0:0:0.3"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </EventTrigger>
                    </RadioButton.Triggers>
                </RadioButton>


Grazie mille per gli aiuti :)
Ultima modifica effettuata da Roby94 09/04/14 20:15
aaa
10/04/14 11:16
vankraster
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.
aaa
10/04/14 12:07
Roby94
Solo ed esclusivamente System.Timers; ;)
Lo uso per le connessioni e le animazioni le effettuo direttamente in XAML
aaa