C# 启动两个线程按顺序运行,而不是同时运行

C# 启动两个线程按顺序运行,而不是同时运行,c#,C#,我有一个主线程,它控制着一个windows窗体,按下一个按钮,就会执行两个线程。一个用于记录信息,另一个用于读取信息。将这些线程放在线程中的想法是让用户能够在执行时与接口交互 下面是两个线程的创建 Thread recordThread = new Thread(() => RecordData(data)); recordThread.Name = "record"; recordThread.Start(); Thread readThread = new Thread(() =&g

我有一个主线程,它控制着一个windows窗体,按下一个按钮,就会执行两个线程。一个用于记录信息,另一个用于读取信息。将这些线程放在线程中的想法是让用户能够在执行时与接口交互

下面是两个线程的创建

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