Какой правильный шаблон для создания асинхронных сервисов? - PullRequest
2 голосов
/ 21 октября 2010

Вот что я пытаюсь сделать:

public class EmployeeService
{
    public void GetEmployeesAsyc(Action<IEnumerable<Employees>> callback)
    {
        ThreadPool.QueueUserWorkItem(x => {
             var employees = //...fetch employees ...//
             callback(employees);
        });
    }
}

public class ViewModel
{
    private EmployeeService _employeeService;
    private bool _isLoaded;

    public ViewModel() 
    { 
         _employeeService = new EmployeeService();   
         EmployeeList = new ObservableCollection<Employee>();
    }

    public ObservableCollection<Employee> EmployeeList { get; set; }

    public void LoadData()
    {
         if(_isLoaded) return;

         _employeeService.GetEmployeesAsync(employees => 
         {
             EmployeeList.Clear();
             employees.ForEach(employee => EmployeeList.Add(employee));          
         });

         _isLoaded = true;
    }
}

public partial class View : PhoneApplicationPage
{
     private ViewModel _vm;

     public View()
     {
         InitializeComponent();
         _vm = new ViewModel();
         this.Loaded += (sender, e) => _vm.LoadData();
     }
}

Проблема здесь в том, что это вызывает исключение между потоками:

         _employeeService.GetEmployeesAsync(employees => 
         {
             EmployeeList.Clear();
             employees.ForEach(employee => EmployeeList.Add(employee));          
         });

Я могу исправить это, обернув его так:

         _employeeService.GetEmployeesAsync(employees => 
         {
             Dispatcher.BeginInvoke(() =>
             {
                 EmployeeList.Clear();
                 employees.ForEach(employee => EmployeeList.Add(employee));          
             });
         });

но я не уверен, что это правильный путь. Есть предложения?

1 Ответ

3 голосов
/ 21 октября 2010

Нет ничего плохого в использовании диспетчера для получения изменений вашего пользовательского интерфейса из фонового потока в поток пользовательского интерфейса.Это одна из его основных целей.

Некоторые элементы инфраструктуры имеют это встроенное для вас (например, webclient vs httpwebrequest), чтобы избавить вас от необходимости писать код диспетчера, но использование этого может привести к снижению производительности пользовательского интерфейса, есливы выполняете большую работу, потому что у вас больше кода, чем нужно для выполнения в потоке пользовательского интерфейса.Приложения, работающие на устройствах с ограниченными ресурсами, таких как WP7, особенно чувствительны к этому.

...