Questa è una domanda successiva a questa domanda .
Sto cercando di caricare i dati dal mio database che impiegheranno 5-10 secondi, ma voglio che la GUI rimanga reattiva e dovrebbe anche essere cancellabile.
private CancellationTokenSource _source;
public IEnumerable<Measurement> Measurements { get { ... } set { ... } }
private async void LoadData()
{
_source = new CancellationTokenSource();
using (var context = new TraceContext())
{
Measurements = null;
Measurements = await context.Measurements.ToListAsync(_source.Token);
}
}
private void Cancel()
{
if (_source != null)
_source.Cancel();
}
public RelayCommand ReloadCommand
{
get { return _reloadCommand ?? (_reloadCommand = new RelayCommand(Reload)); }
}
private RelayCommand _reloadCommand;
public RelayCommand CancelCommand
{
get { return _cancelCommand ?? (_cancelCommand = new RelayCommand(Cancel)); }
}
private RelayCommand _cancelCommand;
Ho provato alcune cose, ma non riesco a farlo funzionare correttamente, questo carica solo la lista e questo è tutto, non posso cancellarlo.
Dov'è l'errore in questo?
Grazie per averlo portato. Attualmente l'implementazione di questa API asincrona in EF si basa sul provider ADO.NET sottostante per onorare l'annullamento, ma SqlDataReader.ReadAsync ha alcune limitazioni e abbiamo osservato che in molti casi non si annulla immediatamente quando viene richiesta la cancellazione. Abbiamo un bug che stiamo considerando per il fissaggio in EF6 RTM che consiste nell'introdurre i nostri controlli per le richieste di cancellazione tra le letture di righe all'interno dei metodi EF.
Nel frattempo, puoi ovviare a questa limitazione utilizzando ForEachAsync () per aggiungere elementi all'elenco e controllare ogni riga, ad esempio (non completamente testata):
public async static Task<List<T>> MyToListAsync<T>(
this IQueryable<T> source,
CancellationToken token)
{
token.ThrowIfCancellationRequested();
var list = new List<T>();
await source.ForEachAsync(item =>
{
list.Add(item);
token.ThrowIfCancellationRequested();
});
return list;
}