簡體   English   中英

具有耗時任務的列表框選擇,需要更新UI

[英]List box selection with time consuming task that needs to update the UI

當用戶為列表框選擇一個項目時,我有一個執行耗時任務的應用程序。

當用戶選擇一個節目時,應用程序將從tvdb中檢索所有節目信息,並將其顯示在Ui中。

當節目仍在加載時用戶快速更改選擇時,就會出現問題。

我想這樣做,以便用戶可以改變主意,然后在第一次加載時進行另一個選擇,並將該信息顯示在Ui中。

我創建了一個簡單的演示應用程序來演示該問題: 演示應用程序

這就是我試圖做的

列表框選擇事件處理程序

private  void lb1_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            string sid = lb1.SelectedItem.ToString();

            try
            {
                LoadSeries(Int32.Parse(sid));
            }
            catch (FormatException)
            {
                MessageBox.Show("Please enter a valid series id");
            }
        }

負載系列

private void LoadSeries(int _seriesId)
{

    Task<TvdbSeries> series = Task.Factory.StartNew(() =>
    {
        TvdbSeries seriesloaded = null;
        try
        {
            seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
        }
        catch (TvdbInvalidApiKeyException ex)
        {
            MessageBox.Show(ex.Message);
        }
        catch (TvdbNotAvailableException ex)
        {
            MessageBox.Show(ex.Message);
        }

        return seriesloaded;
    }
     );

    series.ContinueWith((antecedent) =>
    {
        UpdateSeries(series.Result);
    },
        TaskScheduler.FromCurrentSynchronizationContext()
    );

}

如果用戶快速更改選擇,則在seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);的行上出現應用程序錯誤seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true); 並在調試器中顯示此消息“ WebClient不支持並發I / O操作。

我確實發現這是因為我在最后一個請求完成之前發出了一個新請求,但是我無法在m_tvdbHandler.GetSeries中鏈接代碼,因為它的功能來自我正在使用的庫,並且有人寫過。

這是庫tvdblib ,我確定問題出在我做事的方式而不是庫。

當用戶進行選擇時,可以禁用UI,直到信息完全加載,並在底部加載時顯示一條消息,請等待。 加載完所有內容后,啟用Ui並隱藏消息。

您將此問題作為C#5.0問題發布,因此應盡可能多地使用async / await

private Task<TvdbSeries> LoadSeriesAsync(int _seriesId)
{

    return Task.Run(() =>
    {
        TvdbSeries seriesloaded = null;
        try
        {
            seriesloaded = m_tvdbHandler.GetSeries(_seriesId, TvdbLanguage.DefaultLanguage, true, true, true, true);
        }
        catch (TvdbInvalidApiKeyException ex)
        {
            MessageBox.Show(ex.Message);
        }
        catch (TvdbNotAvailableException ex)
        {
            MessageBox.Show(ex.Message);
        }

        return seriesloaded;
    }
     );
}

如果有一個LoadSeriesAsync會更好。

一種方法是在檢索序列時禁用lb1

私有異步void lb1_SelectionChanged(對象發送方,SelectionChangedEventArgs e){字符串sid = lb1.SelectedItem.ToString();

try
{
    lb1.IsEnabled = false;
    var series = await LoadSeriesAsync(Int32.Parse(sid));

    UpdateSeries(series);
}
catch (FormatException)
{
    MessageBox.Show("Please enter a valid series id");
    lb1.IsEnabled = true;
}

}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM