Asynchronous 如何在UWP中创建同步新闻提要

Asynchronous 如何在UWP中创建同步新闻提要,asynchronous,uwp,synchronization,Asynchronous,Uwp,Synchronization,我想创建一个简单的新闻提要,我使用web API获取新闻更新,用户可以使用combox选择类别(世界新闻和体育新闻),新闻将每5秒自动更新一次,如果我只选择一次,新闻提要可以自动更新和重复,但如果我更改选择,它将开始显示两个类别。这是我的密码 public async void NewsRepeat() { RootObject2 myNews = await NewsProxy.GetNews(); RootObject3 mySportNews = a

我想创建一个简单的新闻提要,我使用web API获取新闻更新,用户可以使用combox选择类别(世界新闻和体育新闻),新闻将每5秒自动更新一次,如果我只选择一次,新闻提要可以自动更新和重复,但如果我更改选择,它将开始显示两个类别。这是我的密码

public async void NewsRepeat()
    {
        RootObject2 myNews = await NewsProxy.GetNews();
        RootObject3 mySportNews = await sportsNewsProxy.GetSportNews();         
        if (newsTpye.SelectedIndex==0)
        {

            for ( k = 0; k <= 8; k++)
            {

                       newsImage.Source = new BitmapImage(new Uri(myNews.articles[k].urlToImage, UriKind.Absolute));                    
                       showTime.Text = myNews.articles[k].publishedAt.ToString();                   
                    showDescription.Text = "(" + myNews.source + "): " + myNews.articles[k].description;
                    await Task.Delay(5000);                     
            }
        }
        else if (newsTpye.SelectedIndex==1)
        {

            for (k = 0; k <= 8; k++)
            {

                   newsImage.Source = new BitmapImage(new Uri(mySportNews.articles[k].urlToImage, UriKind.Absolute));                   
                    showTime.Text = mySportNews.articles[k].publishedAt;                 
                showDescription.Text = "(" + mySportNews.source + "): " + mySportNews.articles[k].description;
                await Task.Delay(5000);
            }        
        }
        NewsRepeat();
    }
private void newsType_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        NewsRepeat();

    }
public异步void newsreat()
{
RootObject2 myNews=await NewsProxy.GetNews();
RootObject3 mySportNews=等待SportNewsProxy.GetSportNews();
if(newsTpye.SelectedIndex==0)
{

对于(k=0;k您的代码连续/无限循环运行。NewsRepeat永远不会结束-因此,当您更改选择时,您现在将并排运行NewsRepeat的两个实例。再次更改它,您将运行三个实例,依此类推

在SelectionChanged上,您希望以某种方式停止上一个NewsRepeat实例的运行

(另外,在ViewModel中创建BitMapImage通常是一个坏主意-直接在XAML中将绑定到URL属性-Windows将为您执行一些性能和内存增强)

一种可能的解决方案是使用CancellationTokenSource,这是一个非常简单的对象,您可以在认为必要时使用它手动抛出OperationCanceledException( 经常用作取消异步任务的模式)。请记住,它不会自动工作-这是您必须处理的事情

    CancellationTokenSource cts = null;
    public async void NewsRepeat()
    {
        cts?.Cancel();

        try
        {
            var localCts = cts = new CancellationTokenSource();

            RootObject2 myNews = await NewsProxy.GetNews();
            RootObject3 mySportNews = await sportsNewsProxy.GetSportNews();

            localCts.Token.ThrowIfCancellationRequested();

            if (newsTpye.SelectedIndex == 0)
            {
                for (k = 0; k <= 8; k++)
                {
                    newsImage.Source = new BitmapImage(new Uri(myNews.articles[k].urlToImage, UriKind.Absolute));
                    showTime.Text = myNews.articles[k].publishedAt.ToString();
                    showDescription.Text = "(" + myNews.source + "): " + myNews.articles[k].description;
                    await Task.Delay(5000);
                    localCts.Token.ThrowIfCancellationRequested();
                }
            }
            else if (newsTpye.SelectedIndex == 1)
            {
                for (k = 0; k <= 8; k++)
                {
                    newsImage.Source = new BitmapImage(new Uri(mySportNews.articles[k].urlToImage, UriKind.Absolute));
                    showTime.Text = mySportNews.articles[k].publishedAt;
                    showDescription.Text = "(" + mySportNews.source + "): " + mySportNews.articles[k].description;
                    await Task.Delay(5000);
                    localCts.Token.ThrowIfCancellationRequested();
                }
            }
            NewsRepeat();
        }
        catch (OperationCanceledException)
        {
            // Swallow this exception only - this is probably
            // the one we've thrown ourselves
        }
    }

    private void newsType_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        NewsRepeat();
    }
CancellationTokenSource cts=null;
公共异步void newsreat()
{
cts?.Cancel();
尝试
{
var localCts=cts=new CancellationTokenSource();
RootObject2 myNews=await NewsProxy.GetNews();
RootObject3 mySportNews=等待SportNewsProxy.GetSportNews();
localCts.Token.ThrowIfCancellationRequested();
如果(newsTpye.SelectedIndex==0)
{

对于(k=0;k您没有向我们显示足够的代码。但一个常见的错误可能是更改选择后没有清除旧列表。您能告诉我如何停止新闻重播吗?我真的不擅长编程,谢谢。@WANGJAY为您添加了一个可能的解决方案@Johnny Westlake谢谢您的帮助,但是,如果我更改选择,它会出现错误:System.OperationCanceledException:“操作已取消。”在“localCts.Token.ThrowIfCancellationRequested();”中,@WANGJAY编辑了答案-您希望捕获“OperationCanceledException”而不是“TaskCanceledException”,因为ThrowIfCancellationRequested实际调用了“if(Token.IsCancellationRequested)”抛出新操作取消异常(令牌);“