Search code examples
c#wpfwcf-data-servicesasync-await

Refresh DataServiceCollection


I wonder if there is a code there that refresh my DataServiceCollection that is loaded in a WPF client using BeginExecute async await Task as show below:

public static async Task<IEnumerable<TResult>> ExecuteAsync<TResult>(this DataServiceQuery<TResult> query)
{
    //Thread.Sleep(10000);
    var queryTask = Task.Factory.FromAsync<IEnumerable<TResult>>(query.BeginExecute(null, null), (asResult) =>
    {
        var result = query.EndExecute(asResult).ToList();
        return result;
    });
    return await queryTask;
}

I call the extension method as the following:

public async void LoadData()
{
   _ctx = new TheContext(the URI);
   _dataSource = new DataServiceCollection<TheEntity>(_ctx);
   var query = _ctx.TheEntity;
   var data = await Task.Run(async () => await query.ExecuteAsync());
   _dataSource.Clear(true);
   _dataSource.Load(data);
}
  1. LoadData is Called in a ViewModel
  2. Change a field value by hand using SQL Management Studio
  3. Call LoadData again <<<< Does not refresh!!!

Meanwhile, If I use Load method the data is refreshed without any problems as:

var query = _ctx.TheEntity;
_dataSource.Load(query);

Another issue is that I do not know how to Cancel client changes. Last question is whether the MergeOption has any effect to BeginExecute..EndExecute or it only works with Load method?


Solution

  • I suspect that the data context does not like being accessed from multiple threads.

    I recommend that you first remove all processing from your extension method:

    public static Task<IEnumerable<TResult>> ExecuteAsync<TResult>(this DataServiceQuery<TResult> query)
    {
      return Task.Factory.FromAsync(query.BeginExecute, query.EndExecute, null);
    }
    

    Which you should use without jumping onto a background thread:

    public async Task LoadDataAsync()
    {
      _ctx = new TheContext(the URI);
      _dataSource = new DataServiceCollection<TheEntity>(_ctx);
      var query = _ctx.TheEntity;
      var data = await query.ExecuteAsync();
      _dataSource.Clear(true);
      _dataSource.Load(data);
    }