WPF Mvvm async function ViewModel I worried about this code in a ViewModel. ViewModel should not contain any code except binding's. But without async update the ui would freeze. How do I improve it? I'm restricted to using .net 3.5 or below.

public ShippingDocumentsRegisterViewModel()
{
    this.Columns = model.InitializeColumns();
    Action&lt;object&gt; Documents = new Action&lt;object&gt;(GetDocumentsAsync);
    IAsyncResult result = Documents.BeginInvoke(new AsyncCallback(GetDocumentsAsync),null, null);
}

public void GetDocumentsAsync(object param)
{
    this.ShippingDocuments = model.GetDocuments();
}


Model:

class ShippingDocumentsModel
    {
        public ObservableCollection&lt;ShippingDocument&gt; GetDocuments()
        {
            var documents = new ObservableCollection&lt;ShippingDocument&gt;();
            for (int i = 0; i &lt; 100; i++)
            {
                System.Threading.Thread.Sleep(50);
                documents.Add(new ShippingDocument { Name = i.ToString() });
            }
            return documents;
        }

        public ObservableCollection&lt;ShippingDocumentColumDescriptor&gt; InitializeColumns()
        {
            return new ObservableCollection&lt;ShippingDocumentColumDescriptor&gt;
            {
                new ShippingDocumentColumDescriptor { HeaderText = "Статус", DisplayMember = "Status" },
                new ShippingDocumentColumDescriptor { HeaderText = "Підпис", DisplayMember = "Signature" }
            };
        }
    }


ViewModel:

public class ShippingDocumentsRegisterViewModel : ViewModelBase
    {
        ShippingDocumentsModel model = new ShippingDocumentsModel();

        public ShippingDocumentsRegisterViewModel()
        {
            this.Columns = model.InitializeColumns();
            Action&lt;object&gt; Documents = new Action&lt;object&gt;(GetDocumentsAsync);
            IAsyncResult result = Documents.BeginInvoke(new AsyncCallback(GetDocumentsAsync),null, null);
        }

        public void GetDocumentsAsync(object param)
        {
            this.ShippingDocuments = model.GetDocuments();
        }

        private ObservableCollection&lt;ShippingDocument&gt; shippingDocuments;

        public ObservableCollection&lt;ShippingDocument&gt; ShippingDocuments
        {
            get
            {
                return shippingDocuments;
            }

            private set
            {
                shippingDocuments = value;
                RaisePropertyChanged("ShippingDocuments");
            }
        }

        public ObservableCollection&lt;ShippingDocumentColumDescriptor&gt; Columns { get; private set; }

        private ICommand _addColumnCommand;

        public ICommand AddColumnCommand
        {
            get
            {
                if (_addColumnCommand == null)
                {
                    _addColumnCommand = new RelayCommand&lt;string&gt;(
                        s =&gt;
                        {
                            this.Columns.Add(new ShippingDocumentColumDescriptor { HeaderText = s, DisplayMember = s });
                        });
                }
                return _addColumnCommand;
            }
        }

        private ICommand _removeColumnCommand;

        public ICommand RemoveColumnCommand
        {
            get
            {
                if (_removeColumnCommand == null)
                {
                    _removeColumnCommand = new RelayCommand&lt;string&gt;(
                        s =&gt;
                        {
                            this.Columns.Remove(this.Columns.FirstOrDefault(d =&gt; d.DisplayMember == s));
                        });
                }
                return _removeColumnCommand;
            }
        }
    }


Edit:

I think maybe this solution would be better?

BackgroundWorker BW = new BackgroundWorker();
            BW.DoWork += (o, e) =&gt; 
            { 
                this.ShippingDocuments = model.GetDocuments(); 
            };
            BW.RunWorkerAsync();
General


Your model should not return an ObservableCollection because that collection should be used only if its change notification ability is needed (e.g. with data binding). The method GetDocuments should return an Array or an IEnumerable.
The method InitializeColumns also seems to be GUI related. Consider moving it to the view model.


Background Processing

If you have to load documents in the background, I would suggest using BackgroundWorker (for .Net Framework 3.5 and below). But you should use it more like:


Pass the model to the RunWorkerAsyncmethod and use the Argument property to access it.
Do not access view model properties from within the DoWork delegate because that is the code that will be executed in the background. Assign the calculated result to the Result property instead.
Use the RunWorkCompleted method to process the calculated result on the GUI thread.


e.g:

var bw = new BackgroundWorker();
bw.DoWork += (o, e) =&gt; e.Result = (e.Argument as Model).GetDocuments();
bw.RunWorkerCompleted += (s, e) =&gt; ShippingDocuments = new ObservableCollection((ShippingDocument[])e.Result);
bw.RunWorkerAsync(model);