У меня есть 3 потока: основной поток, поток readData и поток для сбора. Из формы, когда нажата кнопка воспроизведения, начинается процесс получения устройства и потоков readData. Когда нажата кнопка «Стоп», я хочу остановить оба потока. Однако acqusitionThread.Join() блокирует выполнение. Что я делаю не так?C# Thread.Join() блокирует основной поток
Главная форма
private void btnPlay_Click(object sender, EventArgs e)
{
daqObj.Start();
}
private void btnStop_Click(object sender, EventArgs e)
{
daqObj.Stop();
}
класс acqusition данных для считывания данных с устройства
public void Start()
{
_isRunning = true;
acquisitionDevice.StartAcquisition(); //starts thread for acquisition
//start data acquisition thread
_readDataThread = new Thread(readData);
_readThread.Name = "Read data Thread";
_redThread.Priority = ThreadPriority.AboveNormal;
_readThread.Start();
}
public void ReadData()
{
try
{
// write data to file
while (_isRunning)
{
//Reads data (dequeues from buffer)
float[] data = acquisitionDevice.ReadData(numValuesAtOnce);
//Do other stuff with data (eg: save to file)
}
}
catch (Exception ex)
{
Console.WriteLine("\t{0}", ex.Message);
}
}
public void Stop()
{
_isRunning = false;
if ((_writeToFileThread != null) && _writeToFileThread.IsAlive)
_writeToFileThread.Join(); //stop readData thread
acquisitionDevice.StopAcquisition(); //stops acquisition thread
Console.WriteLine("acquisiton thread stopped); //THIS IS NEVER EXECUTED
}
устройств класса acqusition:
public void StartAcquisition(Dictionary<string, DeviceConfiguration> deviceSerials)
{
//ensure that data acquisition is not already running
if (_isRunning || (_acquisitionThread != null && _acquisitionThread.IsAlive))
throw new InvalidOperationException("Data acquisition is already running!");
_isRunning = true;
//initialize buffer
_buffer = new WindowedBuffer<float>(BufferSizeSeconds * sampleRate * totalChannels);
//start data acquisition thread
_acquisitionThread = new Thread(DoAcquisition);
_acquisitionThread.Name = "DataAcquisition Thread";
_acquisitionThread.Priority = ThreadPriority.Highest;
_acquisitionThread.Start(deviceSerials);
}
public void StopAcquisition()
{
//tell the data acquisition thread to stop
_isRunning = false;
//wait until the thread has stopped data acquisition
if (_acquisitionThread != null)
_acquisitionThread.Join(); //THIS BLOCKS
Console.WriteLine("ended"); //THIS IS NEVER EXECUTED
}
EDIT Вместо отдельной нити для чтения a, я делаю это внутри отмены токена. Я использую отдельный поток для сбора данных формируют устройство (это необходимо для непрерывного получения данных), а затем я прочитал его и записать его в файл с символическим cancellation.This это код, который работает:
public void StartAcquisition()
{
// Initialize token
_cancellationTokenSourceObj = new CancellationTokenSource();
var token = _cancellationTokenSourceObj.Token;
Task.Factory.StartNew(() =>
{
// Start acquisition
try
{
// Write device configuration parameters to .txt file
System.IO.StreamWriter file = new System.IO.StreamWriter(deviceConfFilePath);
file.WriteLine(gUSBampObj.GetDeviceConfigurationString());
file.Close();
// create file stream
using (_fileStream = new FileStream(daqFilePath, FileMode.Create))
{
using (BinaryWriter writer = new BinaryWriter(_fileStream))
{
// start acquisition thread
deviceAcquisition.StartAcquisition();
// write data to file
while (!token.IsCancellationRequested)
{
float[] data = deviceAcquisition.ReadData(numValuesAtOnce);
// write data to file
for (int i = 0; i < data.Length; i++)
writer.Write(data[i]);
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("\t{0}", ex.Message);
}
}, token)
.ContinueWith(t =>
{
//This will run after stopping, close files and devices here
// stop data acquisition
deviceAcquisition.StopAcquisition();
});
}
}
public void StopAcquisition()
{
_cancellationTokenSourceObj.Cancel();
}
Это именно то, что 'Join()' делает. Чего вы ожидаете? – SLaks
Вам нужно каким-то образом прервать 'ReadData()' (который предположительно является блокирующим вызовом) – SLaks
Почему он не возвращается? Почему Console.WritLine («закончился»); никогда не выполняется, если поток завершен? – nabrugir