IMO, questo dipende in gran parte dal tuo ambiente esatto, ma prima di tutto - Non dovresti usare Thread più nella maggior parte dei casi. Tasks
sono la soluzione più comoda e più potente per questo.
a bassa frequenza di polling: Timer + polling in caso Tick
:
Un timer è facile da gestire e fermare. Non c'è bisogno di preoccuparsi di fili/compiti in esecuzione in background, ma la gestione avviene nel thread principale
media frequenza di polling: Task
+ await Task.Delay(delay)
:
await Task.Delay(delay)
non blocca un thread-pool di thread, ma a causa della cambio di contesto il ritardo minimo è ~ 15ms
alta frequenza di polling: Task
+ Thread.Sleep(delay)
utilizzabile a 1ms ritardi - abbiamo effettivamente fare questo per interrogare il nostro dispositivo di misurazione USB
Questo potrebbe essere realizzato nel modo seguente:
int delay = 1;
var cancellationTokenSource = new CancellationTokenSource();
var token = cancellationTokenSource.Token;
var listener = Task.Factory.StartNew(() =>
{
while (true)
{
// poll hardware
Thread.Sleep(delay);
if (token.IsCancellationRequested)
break;
}
// cleanup, e.g. close connection
}, token, TaskCreationOptions.LongRunning, TaskScheduler.Default);
Nella maggior parte dei casi si può semplicemente utilizzare Task.Run(() => DoWork(), token)
, ma non c'è un sovraccarico di fornire l'opzione TaskCreationOptions.LongRunning
che racconta la task-scheduler non utilizzare un normale filettatura filo della piscina
Ma come vedi Tasks
sono più facili da gestire (e await
in grado, ma non si applica qui). Soprattutto lo "stop" è solo chiamando cancellationTokenSource.Cancel()
in questa implementazione da qualsiasi parte del codice.
È possibile condividere questo token in più azioni e fermarle contemporaneamente. Inoltre, le attività non ancora avviate non vengono avviate quando il token viene annullato.
È possibile anche allegare un'altra azione a un'attività a rincorrere un compito:
listener.ContinueWith(t => ShutDown(t));
Questo viene poi eseguito dopo l'ascoltatore completa e si può fare pulizia (t.Exception
contiene l'eccezione dell'azione compiti se non ha avuto successo).
Perché dovremmo odiare il polling? –
Esiste un evento come .OnFinalPositionArrived a cui è possibile connettersi? – Einer
Dovresti usare un 'System.Threading.Timer' per eseguire il polling - che evita di creare un nuovo thread per farlo. –