C# 启动两个线程按顺序运行,而不是同时运行
我有一个主线程,它控制着一个windows窗体,按下一个按钮,就会执行两个线程。一个用于记录信息,另一个用于读取信息。将这些线程放在线程中的想法是让用户能够在执行时与接口交互 下面是两个线程的创建C# 启动两个线程按顺序运行,而不是同时运行,c#,C#,我有一个主线程,它控制着一个windows窗体,按下一个按钮,就会执行两个线程。一个用于记录信息,另一个用于读取信息。将这些线程放在线程中的想法是让用户能够在执行时与接口交互 下面是两个线程的创建 Thread recordThread = new Thread(() => RecordData(data)); recordThread.Name = "record"; recordThread.Start(); Thread readThread = new Thread(() =&g
Thread recordThread = new Thread(() => RecordData(data));
recordThread.Name = "record";
recordThread.Start();
Thread readThread = new Thread(() => ReadData(data));
readThread.Name = "read";
readThread.Start();
数据只是一个数据对象,用于存储记录期间记录的数据
我面临的问题是,第一个线程执行得很好,第二个线程拒绝运行,直到第一个线程完成。在第二个threads函数中放置一个断点,ReadData让我知道只有在第一个线程完成所有记录后才会调用它
我已经试着解决这个问题好几个小时了,但我不明白为什么它会这样做。加入
while(readThread.IsAlive) { }
启动后立即停止执行之后的任何操作,其状态为运行。但它不会使用给定的方法
有什么想法吗
编辑:
线程调用的两个函数是:
private void RecordData(Data d)
{
int i = 0;
while (i < time * freq)
{
double[] data = daq.Read();
d.AddData(data);
i++;
}
}
private void ReadData(Data d)
{
UpdateLabelDelegate updateData =
new UpdateLabelDelegate(UpdateLabel);
int i = 0;
while (i < time * freq)
{
double[] data = d.ReadLastData();
this.Invoke(updateData, new object[] { data });
i++;
}
}
私有无效记录数据(数据d)
{
int i=0;
while(i
数据对象在调用的两个函数中都具有锁定;ReadLastData和Read
以下是数据对象中的方法
public void AddData(双[]数据)
{
锁(这个)
{
int i=0;
foreach(数据中的双d)
{
移动数据[i]。添加(d);
i++;
}
}
}
public double[]ReadLastData()
{
双[]数据=新双[通道];
锁(这个)
{
int i=0;
foreach(移动数据中的列表)
{
数据[i]=列表[list.Count-1];
}
}
返回数据;
}
能否尝试在RecordData中添加睡眠?
也许只是你的(单cpu???)windows操作系统不让第二个线程获得cpu资源
不要这样做:
锁(这个)
改为这样做:
private object oLock = new object();
[...]
lock (this.oLock)
编辑:
你能试试这样的电话吗:
Thread recordThread = new Thread((o) => RecordData((Data)o));
recordThread.Name = "record";
recordThread.Start(data);
您可以尝试在RecordData中添加睡眠吗? 也许只是你的(单cpu???)windows操作系统不让第二个线程获得cpu资源 不要这样做: 锁(这个) 改为这样做:
private object oLock = new object();
[...]
lock (this.oLock)
编辑:
你能试试这样的电话吗:
Thread recordThread = new Thread((o) => RecordData((Data)o));
recordThread.Name = "record";
recordThread.Start(data);
看起来你在阅读/写作之间有一个竞争条件。在第一个线程中,您在向对象添加数据的同时锁定对象,在第二个线程中,您尝试对其进行独占锁定以开始读取。然而,问题是第一个线程执行得太快,以至于第二个线程根本没有机会获得锁 这个问题的解决办法实际上取决于你在这里追求什么样的行为。如果您希望在每次写入之后都能获得连续读取,那么您需要做的是控制读取/写入操作之间的执行,例如
static AutoResetEvent canWrite = new AutoResetEvent(true); // default to true so the first write happens
static AutoResetEvent canRead = new AutoResetEvent(false);
...
private void RecordData(Data d)
{
int i = 0;
while (i < time * freq)
{
double[] data = daq.Read();
canWrite.WaitOne(); // wait for the second thread to finish reading
d.AddData(data);
canRead.Set(); // let the second thread know we have finished writing
i++;
}
}
private void ReadData(Data d)
{
UpdateLabelDelegate updateData =
new UpdateLabelDelegate(UpdateLabel);
int i = 0;
while (i < time * freq)
{
canRead.WaitOne(); // wait for the first thread to finish writing
double[] data = d.ReadLastData();
canWrite.Set(); // let the first thread know we have finished reading
this.Invoke(updateData, new object[] { data });
i++;
}
}
static AutoResetEvent canWrite=new AutoResetEvent(true);//默认为true,因此第一次写入发生
静态自动重置事件canRead=新自动重置事件(false);
...
私有无效记录数据(数据d)
{
int i=0;
while(i
看起来您在读写之间存在竞争条件。在第一个线程中,您在向对象添加数据的同时锁定对象,在第二个线程中,您尝试对其进行独占锁定以开始读取。然而,问题是第一个线程执行得太快,以至于第二个线程根本没有机会获得锁
这个问题的解决办法实际上取决于你在这里追求什么样的行为。如果您希望在每次写入之后都能获得连续读取,那么您需要做的是控制读取/写入操作之间的执行,例如
static AutoResetEvent canWrite = new AutoResetEvent(true); // default to true so the first write happens
static AutoResetEvent canRead = new AutoResetEvent(false);
...
private void RecordData(Data d)
{
int i = 0;
while (i < time * freq)
{
double[] data = daq.Read();
canWrite.WaitOne(); // wait for the second thread to finish reading
d.AddData(data);
canRead.Set(); // let the second thread know we have finished writing
i++;
}
}
private void ReadData(Data d)
{
UpdateLabelDelegate updateData =
new UpdateLabelDelegate(UpdateLabel);
int i = 0;
while (i < time * freq)
{
canRead.WaitOne(); // wait for the first thread to finish writing
double[] data = d.ReadLastData();
canWrite.Set(); // let the first thread know we have finished reading
this.Invoke(updateData, new object[] { data });
i++;
}
}
static AutoResetEvent canWrite=new AutoResetEvent(true);//默认为true,因此第一次写入发生
静态自动重置事件canRead=新自动重置事件(false);
...
私有无效记录数据(数据d)
{
int i=0;
while(i