我正在使用Visual Studio 2015,WPF,C#。
这是复制错误的较大项目的示例代码。
测试项目来源:
https://www.dropbox.com/s/xtlpfhecm1mfv5m/Downloader.zip?dl=0
我有一个ComboBox,您可以在其中选择文件下载。
在示例中,它将StackOverflow徽标png从imgur下载到Downloads文件夹。
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") { ... }
但我宁愿不必这样做。
<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;
});
}