什么是创建异步服务的正确模式?

时间:2010-10-21 00:05:08

标签: .net multithreading silverlight asynchronous windows-phone-7

这是我正在尝试做的事情:

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 个答案:

答案 0 :(得分:3)

使用调度程序将您的UI更改从后台线程更改到UI线程没有任何问题。这是其中一个主要目的。

一些框架元素已经为您内置了(例如webclient vs httpwebrequest),以免您编写调度程序代码的麻烦,但是如果您正在做大量的工作,那么使用它会导致UI性能下降拥有比您在UI线程上执行的代码更多的代码。在具有受限资源的设备上运行的应用程序(如WP7)对此特别敏感。