我正在构建一个概念验证应用程序,然后才能推出真实应用程序。
情景 我应该可以在它的中间停止处理。
工具栏2按钮“开始”& “停止”
用户按下开始并处理长时间运行的任务。 用户决定突然停止任务。
我似乎无法正确穿线!!我不能按下停止状态,因为它正在等待长时间运行的任务,就像长时间运行的任务实际上是在UI线程上运行而不是在后台线程上那样。
我做错了什么你能发现它吗?谢谢你的帮助
public partial class TestView : UserControl
{
private readonly BackgroundWorker _worker;
public TestView
{
InitializeComponent();
_worker = new BackgroundWorker();
_worker.RunWorkerCompleted += RunWorkerCompleted;
_worker.DoWork+=DoWork;
_worker.WorkerReportsProgress = true;
_worker.ProgressChanged+=_worker_ProgressChanged;
_worker.WorkerSupportsCancellation = true;
}
static void RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
MessageBox.Show("The task has been cancelled");
}
else if (e.Error != null)
{
MessageBox.Show("Error. Details: " + e.Error);
}
else
{
MessageBox.Show("The task has been completed. Results: " + e.Result);
}
}
private delegate void SimpleDelegate();
void DoWork(object sender, DoWorkEventArgs e)
{
for (var i = 0; i < 1000000; i++)
{
_worker.ReportProgress(i, DateTime.Now);
// SimpleDelegate simpleDelegate = () => txtResult.AppendText("Test" + System.Environment.NewLine);
//Dispatcher.BeginInvoke(DispatcherPriority.Normal, simpleDelegate);
}
MessageBox.Show("I have done it all");
}
private void _worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
DateTime time = Convert.ToDateTime(e.UserState);
txtResult.AppendText(time.ToLongTimeString());
txtResult.AppendText(Environment.NewLine);
}
private void BtnStart_Click(object sender, RoutedEventArgs e)
{
_worker.RunWorkerAsync();
}
private void BtnStop_Click(object sender, RoutedEventArgs e)
{
_worker.CancelAsync();
MessageBox.Show("Process has been stopped!");
}
}
答案 0 :(得分:3)
您在DoWork内部运行一个非常紧密的循环,并不断将Invoked ProgressUpdates推送到主线程。那会让它变得迟钝。
但真正的问题是DoWork必须合作取消:
void DoWork(object sender, DoWorkEventArgs e)
{
for (var i = 0; i < 1000000; i++)
{
if (_worker.CancelationPending)
{
e.Cancel = true;
break; // or: return to skip the messagebox
}
_worker.ReportProgress(i, DateTime.Now);
}
MessageBox.Show("I have done it all"); // remove or make depend on Cancelled
}