Ho provato ad utilizzare il metodo SwitchTo oggi per passare al thread GUI e ho scoperto che l'esempio da cui l'ho generato non funziona, semplicemente perché il metodo non è presente.Perché lo switch "SwitchTo" è stato rimosso da Async CTP/Release?
Poi ho trovato questo trafiletto here:
La ragione ci siamo sbarazzati di che era perché era così pericoloso. L'alternativa è di impacchettare il codice all'interno TaskEx.Run ...
La mia domanda è semplice: perché era pericoloso? Quali sono i pericoli specifici che l'avrebbero utilizzata?
Si noti che I ha fatto leggere il resto di quel post, quindi capisco ci sono limitazioni tecniche qui. La mia domanda è ancora, se sono a conoscenza di questo, perché è pericoloso?
Sto pensando di reimplementare metodi di supporto per darmi la funzionalità specificata, ma se c'è qualcosa di fondamentalmente rotto, a parte che qualcuno ha deciso che era pericoloso, non lo farei.
In particolare, molto ingenuamente, ecco come vorrei prendere in considerazione l'attuazione dei metodi richiesti:
public static class ContextSwitcher
{
public static ThreadPoolContextSwitcher SwitchToThreadPool()
{
return new ThreadPoolContextSwitcher();
}
public static SynchronizationContextSwitcher SwitchTo(this SynchronizationContext synchronizationContext)
{
return new SynchronizationContextSwitcher(synchronizationContext);
}
}
public class SynchronizationContextSwitcher : INotifyCompletion
{
private readonly SynchronizationContext _SynchronizationContext;
public SynchronizationContextSwitcher(SynchronizationContext synchronizationContext)
{
_SynchronizationContext = synchronizationContext;
}
public SynchronizationContextSwitcher GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get
{
return false;
}
}
public void OnCompleted(Action action)
{
_SynchronizationContext.Post(_ => action(), null);
}
public void GetResult()
{
}
}
public class ThreadPoolContextSwitcher : INotifyCompletion
{
public ThreadPoolContextSwitcher GetAwaiter()
{
return this;
}
public bool IsCompleted
{
get
{
return false;
}
}
public void OnCompleted(Action action)
{
ThreadPool.QueueUserWorkItem(_ => action(), null);
}
public void GetResult()
{
}
}
Questo mi avrebbe permesso di scrivere codice in questo modo:
public async void Test()
{
await ContextSwitcher.SwitchToThreadPool(); // ensure we're not bogging down the UI thread
// do some heavy processing
await _UIContext.SwitchTo(); // presumably saved from the main thread
// update UI with new data
}
Hah.Questo è piuttosto un vecchio thread! Non sono mai stato un fan del ragionamento occasionale di Microsoft "è per il tuo bene". –
Da allora sono passato a fare 'Attendere Task.Run (async() => {})' - non per evitare alcuni pericoli vuoti, ma semplicemente perché penso che sia più facile da leggere. Penso che la tua idea di come implementare 'SwitchTo()' sia valida, comunque. –
Non conoscevo la sintassi 'async() => {}', ha bisogno di ulteriori indagini, grazie! –