jus*_*inf 5 c# c#-5.0 .net-4.5
我有以下任务,当列表框的节项更改时运行.
我试图取消当用户更改其选择并开始新任务时正在运行的任何任务.我似乎可以弄清楚为什么代码不起作用.
代码
CancellationTokenSource cts;
// The event handeler for when the user makes a selection in the list box
private async void lb1_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
clearfileds();
if (cts != null)
{ cts.Cancel(); }
cts = new CancellationTokenSource();
var token = cts.Token;
string sid = lb1.SelectedItem.ToString();
try
{
var series = await LoadSeriesAsync(token, Int32.Parse(sid));
var poster = await LoadPosterAsync(series.PosterBanners[0]);
UpdateSeries(series);
if (File.Exists(poster))
{
ImageSource imageSource = new BitmapImage(new Uri(poster));
imgPoster.Source = imageSource;
}
}
catch (OperationCanceledException)
{MessageBox.Show("we cancell some thing");}
catch (FormatException)
{MessageBox.Show("Please enter a valid series id");}
}
private async Task<TvdbSeries> LoadSeriesAsync(CancellationToken ct, int _seriesId)
{ TvdbSeries seriesloaded = null;
CancellationToken token = ct;
Task<TvdbSeries> SeriesLoadTask = Task.Run(() =>
{
m_tvdbHandler = new TvdbHandler(CacheProvider, "49E28C3EB13EB1CF");
m_tvdbHandler.InitCache();
token.ThrowIfCancellationRequested();
try
{ seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
//Just for the test
System.Threading.Thread.Sleep(9000);
}
catch (OperationCanceledException)
{ }
catch (TvdbInvalidApiKeyException ex)
{ MessageBox.Show(ex.Message);}
catch (TvdbNotAvailableException ex)
{ MessageBox.Show(ex.Message);}
return seriesloaded;
});
try
{ seriesloaded = await SeriesLoadTask; }
catch (OperationCanceledException)
{}
return seriesloaded;
}
private async Task<string> LoadPosterAsync(object _param)
{
string posterpath ;
Task<string> PosterLoad = Task.Run(() =>
{
TvdbPosterBanner banner = (TvdbPosterBanner)_param;
banner.LoadBanner();
posterpath = CacheFolder + @"\" + banner.SeriesId + @"\img_posters_" + (banner.BannerPath).Replace(@"posters/", "");
return posterpath;
});
try
{ posterpath = await PosterLoad; }
catch (OperationCanceledException)
{
posterpath = "";
}
return posterpath;
}
Run Code Online (Sandbox Code Playgroud)
所以我试图让LoadSeriesAsync取消所有正在运行的其他事件,然后只运行LoadPosterAsync如果LoadSeriesAsync被允许完成(加载之前,用户不更改选择).
我试图让 LoadSeriesAsync 取消正在运行的所有其他事件,然后仅在允许 LoadSeriesAsync 完成时才运行 LoadSeriesAsync
因此,只需在调用之前检查令牌即可LoadPosterAsync:
var series = await LoadSeriesAsync(token, Int32.Parse(sid));
token.ThrowIfCancellationRequested();
var poster = await LoadPosterAsync(series.PosterBanners[0]);
Run Code Online (Sandbox Code Playgroud)
附带说明一下,您应该将token堆栈向下传递给任何长时间运行的操作,例如TvdbHandler.GetSeries.
而且,这通常是一个坏主意catch (OperationCanceledException) { };通常,所需的语义是允许取消传播出去。
| 归档时间: |
|
| 查看次数: |
262 次 |
| 最近记录: |