2010-09-20 2 views
1

Я использую очень часто RIA WCF Services, и я вставляю тот же контекст в несколько ViewModel. Моя проблема заключается в том, что, как вы знаете, контекст служб RIA не является потокобезопасным.Thread safe, Silverlight

Так что я принимаю решение «для дома» для синхронизации. Я использую фоновые рабочие, и используя PostSharp, я применяю свой атрибут [UniqueThread («Данные»)] по методу и voila.

Я что-то усложняю? Существуют ли более простые решения?

С наилучшими пожеланиями,
Винсент BOUZON

ответ

0

Это, конечно, кажется слишком сложным, если вы не сделали много другой работы, чтобы заставить ваши ViewModels быть запущен в отдельных потоках. По умолчанию, конечно, все, что вы пишете, будет запущено в основной основной теме, и не должно быть необходимости заниматься сложным материалом, который вы описываете. Или ваши модели на самом деле работают на отдельных (фоновых) потоках?

+0

Это не так уж сложно. Но, например, объект, созданный для служб RIA, не должен выполняться в потоке пользовательского интерфейса, он занимает слишком много времени, после чего пользовательский интерфейс блокируется. Итак, все, что касается контекста RIA, работающего на фоновом потоке, и мой пользовательский интерфейс более жидкий. –

+0

Я сделал аналогичные вещи в своих проектах, где я перемещаю всю связь WCF с фоновыми потоками, используя ThreadPool.QueueUserWorkItem(). Это не так много, что он ускоряет работу, так как делает интерфейс более плавным. Но тогда я в основном делаю то, что отвечает HiTech Magic, а именно, использовать Dispatcher.BeginInvoke() для маршалирования данных обратно в поток пользовательского интерфейса, когда это необходимо. Но я не пользуюсь услугами RIA, поэтому мне не пришлось беспокоиться о синхронизации доступа к его контексту. Будет ли простой объект блокировки (например, «lock (myRiaContext) {}») предоставить вам необходимую синхронизацию? –

+0

Да, конечно, я также использую блокировку в том, что вводит PostSharp. –

4

В нашем случае мы добавили метод OnUiThread в наш BaseViewModel (который также поставляет обработчик INotifypropertyChanged и некоторые другие полезные методы использования).

Когда нам нужен, чтобы убедиться, что операция выполняется в потоке пользовательского интерфейса, мы вызываем OnUiThread с выражением лямбда (или обратным вызовом) для выполнения работы.

protected delegate void OnUiThreadDelegate(); 

protected void OnUiThread(OnUiThreadDelegate onUiThreadDelegate) 
{ 
    if (Deployment.Current.Dispatcher.CheckAccess()) 
    { 
     onUiThreadDelegate(); 
    } 
    else 
    { 
     Deployment.Current.Dispatcher.BeginInvoke(onUiThreadDelegate); 
    } 
} 

Пример вызова может выглядеть следующим образом:

this.OnUiThread(() => 
    { 
     this.ViewModelList = resultList; 
    });