我有一个小程序,它应该从通过USB连接的设备中取样一些值。 我想每隔0.5秒对设备进行一次采样 - 所以我创建了一个每500毫秒重复一次的循环并且运行良好:
while(_bool)
{
Sample_USB_Device();
Present_Data_To_Screen();
}
我的问题是:
如何控制_bool
变量?当我运行代码时,GUI冻结,我没有任何访问权限。我试图使用Threads,但是我无法将数据从线程发送回GUI(或者我不知道如何)。
答案 0 :(得分:7)
您可以使用Timer以指定的时间间隔运行代码,而不是使用循环。可以启用或禁用计时器。
答案 1 :(得分:0)
使用线程:
public class ThreadExample {
private bool _running;
public void start() {
Thread t = new Thread(doStuff);
_running = true;
t.Start();
}
public void stop() {
_running = false;
}
public void doStuff() {
while(_running){
Sample_USB_Device();
Present_Data_To_Screen();
Thread.Sleep(500);
}
}
}
答案 2 :(得分:0)
答案 3 :(得分:0)
在这里,使用背景。
backgroundWorker1.RunWorkerAsync(); // Start the backgroundworker.
private void backgroundWorker1_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{
// Do you stuff here.
}
private void backgroundWorker1_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e)
{
// Report the changes.
// NOTE: backgroundWorker1.WorkerReportsProgress = true; has to be true.
}
private void backgroundWorker1_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
{
// Do something when we are done.
}
编辑:这只会阻止您的冻结问题。
答案 4 :(得分:0)
使用BackgroundWorker在后台执行循环。这将确保您的UI保持响应:
BackgroundWorker bw;
public void StartBackgroundLoop() {
bw = new BackgroundWorker();
bw.WorkerSupportsCancellation = true;
bw.WorkerReportsProgress = true;
bw.DoWork += (sender, e) => {
// this will happen in a background thread
while (!bw.CancellationPending) {
data = Sample_USB_Device();
bw.ReportProgress(0, data);
}
}
// this event is triggered *in the UI thread* by bw.ReportProgress
bw.ProgressChanged += (sender, e) => {
Data data = (Data)e.UserState; // this is the object passed to ReportProgress
Present_Data_To_Screen(data);
}
bw.RunWorkerAsync(); // starts the background worker
}
public void StartBackgroundLoop() {
bw.CancelAsync(); // sets bw.CancellationPending to true
}
答案 5 :(得分:0)
使用Timer与C#5.0& TPL将允许您以定义的时间间隔调用异步事件处理程序,该处理程序将轮询设备并自动将结果编组回UI线程。
public partial class Form1 : Form
{
private readonly Timer _sampleTimer;
public Form1()
{
InitializeComponent();
_sampleTimer = new Timer
{
Interval = 500 // 0.5 Seconds
};
_sampleTimer.Tick += SampleUsb;
}
private async void SampleUsb(object sender, EventArgs e)
{
// Since we asynchronously wait, the UI thread is not blocked by "the work".
var result = await SampleUsbDeviceAsync();
// Since we resume on the UI context, we can directly access UI elements.
resultTextField.Text = result;
}
private async Task<string> SampleUsbDeviceAsync()
{
await Task.Delay(1000); // Do actual work sampling usb async (not blocking ui)
return DateTime.Now.Ticks.ToString(); // Sample Result
}
private void startButton_Click(object sender, EventArgs e)
{
_sampleTimer.Start();
}
private void stopButton_Click(object sender, EventArgs e)
{
_sampleTimer.Stop();
}