我正在使用async
和await
关键字来使应用程序响应
我View
在ViewModel
.
VIEW:按钮点击事件
private async void button1_Click(object sender, RoutedEventArgs e)
{
button1.IsEnabled = false;
// Property Change
_viewModel.Words = await Task.Factory.StartNew(() => File.ReadAllLines("Words.txt").ToList()); // takes time to read about 3 - 4 seconds
switch (_viewModel.RadioButtonWordOrderSelection)
{
case MainWindowViewModel.RadioButtonWordOrderSelections.NormalOrder:
break;
case MainWindowViewModel.RadioButtonWordOrderSelections.ReverseOrder:
await Task.Factory.StartNew(() =>
{
var words = _viewModel.Words.ToList();
words.Reverse();
// Property Change
_viewModel.Words = words;
});
break;
case MainWindowViewModel.RadioButtonWordOrderSelections.Shuffle:
await Task.Factory.StartNew(() =>
{
// Property Change
_viewModel.Words = _viewModel.Words.Shuffle().ToList();
});
break;
}
await Task.Factory.StartNew(() => DownloadSomething(_viewModel.Words)); // takes time to read about 30 - 40 seconds
button1.IsEnabled = true;
}
_viewModel.Progress
在View
视图:私有方法需要 30 - 40 秒才能完成
private void DownloadSomething(IEnumerable<string> words)
{
// Property Change
_viewModel.Progress = 0;
foreach (var word in words)
{
// Property Change
_viewModel.Word = word;
try
{
// Some code WebClient download code here
}
catch (Exception e)
{
//Trace.WriteLine(e.Message);
}
// Property Change
_viewModel.Progress++;
}
}
VIEW:已处理的属性更改事件
void _viewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
try
{
switch(e.PropertyName)
{
case "Progress":
// Since its a different Thread
// http://msdn.microsoft.com/en-us/magazine/cc163328.aspx
// Sets the Value on a ProgressBar Control.
// This will work as its using the dispatcher
// The following works
//Dispatcher.Invoke(
// DispatcherPriority.Normal,
// new Action<double>(SetProgressValue),
// _viewModel.Progress);
// from http://stackoverflow.com/questions/2982498/wpf-dispatcher-the-calling-thread-cannot-access-this-object-because-a-differen
progress1.Dispatcher.Invoke(
DispatcherPriority.Normal,
new Action(() =>
{
progress1.Value = _viewModel.Progress;
})
);
// This will throw an exception
// (it's on the wrong thread)
//progress1.Value = _viewModel.Progress;
break;
case "Words":
// Since its a different Thread
// http://msdn.microsoft.com/en-us/magazine/cc163328.aspx
// Sets the Max Value on a ProgressBar Control.
// This will work as its using the dispatcher
// The following Works
//Dispatcher.Invoke(
// DispatcherPriority.Normal,
// new Action<double>(SetProgressMaxValue),
// _viewModel.Words.Count);
// from http://stackoverflow.com/questions/2982498/wpf-dispatcher-the-calling-thread-cannot-access-this-object-because-a-differen
progress1.Dispatcher.Invoke(
DispatcherPriority.Normal,
new Action(() =>
{
progress1.Maximum = _viewModel.Words.Count;
})
);
// This will throw an exception
// (it's on the wrong thread)
//progress1.Maximum = _viewModel.Words.Count;
break;
case "Word":
// Since its a different Thread
// http://msdn.microsoft.com/en-us/magazine/cc163328.aspx
// Sets the Contant on a Label Control.
// This will work as its using the dispatcher
// The following Works
//Dispatcher.Invoke(
// DispatcherPriority.Normal,
// new Action<string>(SetLastWordValue),
// _viewModel.Word);
// from http://stackoverflow.com/questions/2982498/wpf-dispatcher-the-calling-thread-cannot-access-this-object-because-a-differen
labelLastWord.Dispatcher.Invoke(
DispatcherPriority.Normal,
new Action(() =>
{
labelLastWord.Content = _viewModel.Word;
})
);
// This will throw an exception
// (it's on the wrong thread)
//labelLastWord.Content = _viewModel.Word;
break;
case "RadioButtonWordOrderSelection":
break;
default:
throw new NotImplementedException("[Not implemented for 'Property Name': " + e.PropertyName + "]");
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message + "\n" + ex.StackTrace);
}
}
为 progressBar1 和 labelLastWord 完美更新了 UI!我遇到了一个问题,当progressBar1 和labelLastWord 正在更新UI 的其余部分时被冻结。
有没有办法解决这个问题?
我非常感谢任何帮助!