我正在制作一个简单的应用程序,我需要做一些事情,并更新进度条。我做了一些事情,等待1秒,如果执行没问题,我会增加进度条,做一些其他的事情,再等一下,如果确定,增加进度条,依此类推,7次。通过东西,这意味着我通过RS232连接到电子板,发送一些命令,然后执行,1秒钟后我检查电路板上是否一切正常。我需要等待1秒才能获得电路板上的一些模拟内容。
问题在于等待一秒钟。如果我使用Thread.Sleep(1000),整个用户界面会冻结(如预期的那样)并且进度条在“未同步”中工作,等待同样的原因。
我的代码就像:
progressBar1.Value = 0;
/* Do some stuff */
Thread.Sleep(1000);
/* Check the stuff */
progressBar1.Value = 1;
/* Do some stuff */
Thread.Sleep(1000);
/* Check the stuff */
progressBar1.Value = 2;
/* Do some stuff */
Thread.Sleep(1000);
/* Check the stuff */
等等... 7次。
每个步骤的“东西”都不同。
哪种方法可以让我的代码等待1秒钟?
Thanx任何帮助!!!
答案 0 :(得分:1)
如果您的.NET Framework版本支持,您应该使用任务并行库(TPL)。这正是TPL旨在解决的问题。为此,您将启动一个异步Task,它是Thread类之上的封装。
从概念上讲,您应该创建一个 new 线程来连接RS232板。您的主线程(UI线程)继续执行,不会冻结UI。如果这是一个Windows应用程序,您应该阅读有关多线程编程的更多信息,因为在Windows应用程序中使用单个线程需要“同时”执行许多操作,这将始终导致阻塞和冻结问题。
如果您的.NET Framework版本不支持TPL,那么您应该使用名为BackgroundWorker的类。这是一个让您入门的小例子:http://msdn.microsoft.com/en-us/library/ywkkz4s1.aspx
PS:我的回答是基于您正在编写Windows窗体应用程序的假设。
答案 1 :(得分:1)
这是一个非常简单,人为的WinForms示例:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Threading.Tasks;
namespace ProgressBar
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void btnDoWork_Click(object sender, EventArgs e)
{
Task task1 = new Task(() => { System.Threading.Thread.Sleep(5000); });
Task task2 = new Task(() => { System.Threading.Thread.Sleep(5000); });
Task task3 = new Task(() => { System.Threading.Thread.Sleep(5000); });
Task task4 = new Task(() => { System.Threading.Thread.Sleep(5000); });
task1.ContinueWith((t) =>
{
if (t.Exception != null)
t.Exception.Handle(ex =>
{
//do something
return true;
});
progressBar.Value = 25;
}, TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith((t) => task2.Start());
task2.ContinueWith((t) =>
{
if (t.Exception != null)
t.Exception.Handle(ex =>
{
//do something
return true;
});
progressBar.Value = 50;
}, TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith((t) => task3.Start());
task3.ContinueWith((t) =>
{
if (t.Exception != null)
t.Exception.Handle(ex =>
{
//do something
return true;
});
progressBar.Value = 75;
}, TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith((t) => task4.Start());
task4.ContinueWith((t) =>
{
if (t.Exception != null)
t.Exception.Handle(ex =>
{
//do something
return true;
});
progressBar.Value = 100;
}, TaskScheduler.FromCurrentSynchronizationContext());
task1.Start();
}
}
}
基本上,只需为每个操作创建一个任务;然后继续执行该任务,检查AggregateException(这非常重要,好像你没有检查它并且有一个例外,当任务被垃圾收集时你的程序会崩溃)。在完成该延续时,只需触发下一个任务。如果您需要从其中一个任务执行UI访问,请确保从CurrentSynchronizationContext调用该任务。