Асинхронный метод длительного вызова Silverlight 4.0 (MVVM) - PullRequest
1 голос
/ 23 марта 2011

Свойства ViewModel моего приложения Silverlight MVVM, которые накапливаются из библиотеки служб (не службы WCF).

Метод библиотеки выполняет некоторые операции, которые могут занять некоторое время. После завершения операции возвращаемое значение присваивается свойству ViewModel.

Поскольку представление привязано к свойству ViewModel, оно будет обновляться автоматически при изменении значения свойства. Но во время операции, как и ожидалось, пользовательский интерфейс перестает отвечать на запросы из-за синхронной работы.

Как выполнить следующую операцию в асинхронном режиме?

Договор на обслуживание и реализация:

public class ItemsLoadedEventArgs : EventArgs
{
    public List<string> Items { get; set; }
}

public interface ISomeService
{
    event EventHandler<ItemsLoadedEventArgs> GetItemsCompleted;

    void GetItemsAsync();
}

public class SomeService : ISomeService
{
    public event EventHandler<ItemsLoadedEventArgs> GetItemsCompleted;

    public void GetItemsAsync()
    {
        // do something long here
        // how to do this long running operation Asynchronously?
        // and then notify the subscriber of the Event?

        // when the operation is completed fire the event
        if(this.GetItemsCompleted != null)
        {
            this.GetItemsCompleted(this, new ItemsLoadedEventArgs { Items = resulthere });
        }
    }
}

ViewModel:

public class HomeViewModel : ViewModel
{
    private ISomeService service;
    private ObservableCollection<string> _items;
    // Items property is bound to UI
    public ObservableCollection<string> Items
    {
        get { return this._items; }
        set 
        {
            this._items = value;
            this.RaisePropertyChanged(() => this.Items);
        }
    }

    // DI
    public HomeViewModel(ISomeService service)
    {
        ...

        this.service = service;

        // load items
        this.LoadItems();
    }

    private void LoadItems()
    {
        this.service.GetItemsCompleted += (s, ea) =>
        {
            this.Items = new ObservableCollection<string>(ea.Items);
        };

        this.service.GetItemsAsync();
    }
}

Проблема:

Поскольку данные загружаются в конструктор, а операция выполняется синхронно, пользовательский интерфейс перестает отвечать на запросы.

Как выполнить операцию внутри метода GetItemsAsync класса SomeService Асинхронно?

1 Ответ

1 голос
/ 23 марта 2011

Используйте Dispatcher.BeginInvoke для вызова метода вашей библиотеки. Вы должны вернуться в поток пользовательского интерфейса, чтобы обновить вашу ViewModel, когда это будет сделано. См. этот вопрос для получения информации по этому вопросу.

...