下载程序线程调度程序导致程序挂起

时间:2017-07-31 05:59:14

标签: c# wpf visual-studio xaml

我正在使用Visual Studio 2015,WPF,C#。

这是复制错误的较大项目的示例代码。

测试项目来源:
https://www.dropbox.com/s/xtlpfhecm1mfv5m/Downloader.zip?dl=0

我有一个ComboBox,您可以在其中选择文件下载。

在示例中,它将StackOverflow徽标png从imgur下载到Downloads文件夹。

Downloader Program

问题

ComboBox SelectedItem错误

if ((string)cboDownload.SelectedItem == "File 1") { ... }

The calling thread cannot access this object because a different thread owns it.

我在Dispatcher内添加Thread

但是当您按下“下载”按钮时,Dispatcher会导致程序冻结。

解决方案

如果我在话题前将ComboBox Selected Item设置为string,我才能使其正常工作:

string cboDownloadItem = cboDownload.SelectedItem.ToString();

if ((string)cboDownloadItem == "File 1") { ... }

但我宁愿不必这样做。

XAML

<Label x:Name="labelProgressInfo" 
       Content="" HorizontalAlignment="Center" 
       Margin="10,55,10,0" 
       VerticalAlignment="Top" 
       Width="497"/>

<ProgressBar x:Name="progressBar" 
             HorizontalAlignment="Left" 
             Height="24" Margin="10,89,0,0"
             VerticalAlignment="Top" 
             Width="487"/>

<ComboBox x:Name="cboDownload" 
          HorizontalAlignment="Left" 
          Margin="122,171,0,0" 
          VerticalAlignment="Top" 
          Width="120" 
          SelectedIndex="0">
    <System:String>File 1</System:String>
    <System:String>File 2</System:String>
</ComboBox>

<Button x:Name="btnDownload"
        Content="Download" 
        HorizontalAlignment="Left"
        Margin="278,173,0,0" 
        VerticalAlignment="Top"
        Width="75"
        Click="btnDownload_Click"/>

字符串

string fileBaseUrl = "https://i.imgur.com/";
string fileName = string.Empty;
string localPath = Environment.ExpandEnvironmentVariables(@"%USERPROFILE%") + "\\Downloads\\";

下载按钮

private void btnDownload_Click(object sender, RoutedEventArgs e)
{
    // Start New Thread
    //
    Thread thread = new Thread(() =>
    {
        Dispatcher.BeginInvoke((MethodInvoker)delegate
        {
            // ComboBox Selected Download
            //
            if ((string)cboDownload.SelectedItem == "File 1")
            {
                // StackOverflow Logo
                fileName = "WTminjY.png";
            }

            waiter = new ManualResetEvent(false);

            Uri downloadUrl = new Uri(fileBaseUrl + fileName);
            wc.DownloadProgressChanged += new DownloadProgressChangedEventHandler(wc_DownloadProgressChanged);
            wc.DownloadFileCompleted += new AsyncCompletedEventHandler(wc_DownloadFileCompleted);
            wc.DownloadFileAsync(downloadUrl, localPath + fileName);

            // Progress TextBox
            progressInfo = "Downloading...";

            // Wait for Download to complete
            waiter.WaitOne();

            // Progress TextBox
            progressInfo = "Download Complete";
        });
    });


    // Start Download Thread
    //
    thread.Start();
}

下载处理程序

public void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
{
    // Progress TextBox
    Dispatcher.BeginInvoke((MethodInvoker)delegate
    {
        labelProgressInfo.Content = progressInfo;
    });

    // Progress Bar
    Dispatcher.BeginInvoke((MethodInvoker)delegate
    {
        double bytesIn = double.Parse(e.BytesReceived.ToString());
        double totalBytes = double.Parse(e.TotalBytesToReceive.ToString());
        double percentage = bytesIn / totalBytes * 100;
        progressBar.Value = int.Parse(Math.Truncate(percentage).ToString());
    });
}


public void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
{
    waiter.Set();

    // Progress TextBox
    Dispatcher.BeginInvoke((MethodInvoker)delegate
    {
        labelProgressInfo.Content = progressInfo;
    });
}

0 个答案:

没有答案