我是C#的新手,并实现了一个代码,其中我有两个按钮,一个用作数据采集的开始并将其存储在csv文件中,另一个按钮用于停止它。
所有这些的代码如下:
//按钮启动DAQ
private void stdaq_Click(object sender, EventArgs e)
{
stopped = false;
process();
}
//用于停止DAQ的按钮
private void spdaq_Click(object sender, EventArgs e)
{
stopped = true;
}
//处理功能
private process()
{
int iAvail = 0;
int iRead = 0;
string filename = @textBox3.Text;// taking csv file name from user
// jit:
//a function calculating the total number of values and storing it in iAvail
int[] iRawData = new Int32[iAvail];
double[] dScaledData = new Double[iAvail];
//a function transferring the data from buffer and storing it in dscaledData array
List<double> data = new List<double>();
for (int i = 0; i < iAvail; i++)
{
data.Add(dScaledData[i]);
}
Task myFirstTask = Task.Factory.StartNew(()
=>
{
while (stopped == false)
{
Write(data.ToArray(), filename);
// goto jit;
}
});
}
// csv creater and data writer
public static void Write(double[] data, string outputPath)
{
StringBuilder sb = new StringBuilder();
for (int i = 0; i < data.GetLength(0); i++)
{
if (stopped) break;
sb.AppendLine(string.Join(",", data[i]));
}
if (File.Exists(outputPath))
{
File.AppendAllText(outputPath, sb.ToString());
}
else
{
File.WriteAllText(outputPath, sb.ToString());
}
}
这就是我正在实现的,这段代码的问题在于,当数据首次传输并写入文件时,无论新数据如何,我都会一次又一次地写入相同的数据,并尝试实现Goto语句(可以在注释中看到)但它给出错误 - “控件不能离开匿名方法或lambda表达式的主体”,如果我不使用While循环,则根本不写入数据。
所以我想调用我的过程函数并在按下开始按钮时将数据传输到csv,每次都获取新数据并将其写入csv,或者可以说从它的起点再次调用过程方法单击停止按钮停止它,但我无法做到这一点,无论各种尝试使用不同的循环和一些线程功能。
请帮助解决这个问题。
答案 0 :(得分:1)
假设您只需要Write
一次,则应将其删除或将其从while
更改为if
:
while (stopped == false)
循环将导致Write
被无限调用,直到stopped
变为true
。
此外,如果Write
为return
,您可能希望将break
更改为stopped
而不是true
,这样您就不会写如果你应该停下来的话:
if (stopped) break;
到
if (stopped) return;
如果你想再次生成data
并且确实想要永远循环,只需将该代码移动到循环中:
Task myFirstTask = Task.Factory.StartNew(()
=>
{
while (stopped == false)
{
List<double> data = new List<double>();
// TODO: Generate data here - move all relevant code here
Write(data.ToArray(), filename);
}
});
答案 1 :(得分:0)
我认为这是 BackgroundWorker 的工作。
此代码将启动您:
public partial class Form1 : Form
{
int loopCounter = 0; // variable just used for illustration
private static BackgroundWorker bw = new BackgroundWorker(); // The worker object
// This function does your task
public void doSomeStuff(object sender, DoWorkEventArgs e)
{
for (int i = 0; i < 1000; i++)
{
loopCounter = i; // Pass the loop count to this variable just to report later how far the loop was when the worker got cancelled.
Thread.Sleep(100); // Slow down the loop
// During your loop check if the user wants to cancel
if (bw.CancellationPending)
{
e.Cancel = true;
return; // quit loop
}
}
}
// This button starts your task when pressed
private void button1_Click(object sender, EventArgs e)
{
bw.WorkerSupportsCancellation = true; // Set the worker to support cancellation
bw.DoWork += doSomeStuff; // initialize the event
if (!bw.IsBusy) // Only proceed to start the worker if it is not already running.
{
bw.RunWorkerAsync(); // Start the worker
}
}
// This button stops your task when pressed
private void button2_Click(object sender, EventArgs e)
{
// Request cancellation
bw.CancelAsync();
textBox1.Text = "The bw was cancelled when 'loopCounter' was at: " + loopCounter.ToString();
}
}