O varianta este de a trasmite o instanta la Dispatcher prin constructor sau cand se face apelul la o metoda data.
public class Context()
{
...
Context(Dispatcher dispatcher)
{
_dispatcher = dispatcher;
}
..
{
_dispatcher.BeginInvoke( () => { ... } );
}
}
O alta varianta destul de des intalnita este sa se obtina o referinta la Distapcher direct prin apelul:Deployment.Current.Dispatcher
Ambele variante functioneaza fara nici o problema. Problema este ca clasele care folosesc acest Dispatcher o sa fie coupled. Aceasta problema se poate observa cel mai usor in momentul in care se scriu teste. Daca testele o sa reluze din brower de exemplu, pana la sfarsitul testelor, threadul de UI o sa fie blocat de rularea acestora, din aceasta cauza nu o sa se ajunga ca codul apelat prin Dispatcher sa fie executat. Pe langa acest lucru in teste dorim sa putem controla cand se ruleaza acest cod.O varianta este sa ne definim o interfata pentru dispatcher-ul de UI, prin intermediul careia sa se poata rula cod pe UI thread. In acest mod, nu o sa mai fie coupled dispatcher-ul de restul aplicatiei. Iar in cazul in care dorim ca codul sa fie executat pe un alt thread sau in alt mod o sa fie nevoie sa ne implementam diferit acesta clasa( de exemplu pentru teste).
public interface IUiDispatcher
{
void Invoke(Action action);
}
public class UiDispatcher : IUiDispatcher
{
private readonly Dispatcher _dispatcher;
public UiDispatcher(Dispatcher dispatcher)
{
_dispatcher = dispatcher;
}
public void InvokeOnUiThread(Action action)
{
// Verificam daca suntem pe UI thread.
if( _dispatcher.CheckAccess())
{
action.Invoke();
}
else
{
_dispatcher.BeginInvoke(action);
}
}
}
Enjoy!
0 comments:
Post a Comment