【问题标题】:C# Stop thread syntax execution without blocking the processC#停止线程语法执行而不阻塞进程
【发布时间】:2017-05-05 11:44:39
【问题描述】:

需要在不阻塞整个进程的情况下在某处停止线程语法执行。 一个新手和奇怪的问题。

解释: 有一个正在运行的线程记录声音,该声音必须在某处等待,直到记录完成才能停止该过程。 StopIt()Recorder() 方法中,我需要在 waveIn.StartRecord() 之后和之前暂停语法执行 StopIt() 直到 bool StopRecording 翻转。

问题:整个StopIt() 需要一段时间才能完成它的工作,但我需要它立即重新启动该过程,以免丢失即将播放的曲目的第一个字节,所以我需要放置Recorder()StopIt() 在同一个线程中,以便能够访问 Recorder() 捕获的数据,并且能够在另一个线程中运行相同的进程,以免在第一个线程完成工作时丢失任何数据。

尝试: 尝试通过许多“错误但它可能有效” 的方式来解决问题,例如: while (StopRecording) {} 但他们造成了很多问题。

守则:

void Recorder()
{
    waveIn = new WasapiLoopbackCapture();
    waveIn.DataAvailable += waveIn_DataAvailable;
    waveIn.RecordingStopped += waveIn_RecordingStopped;
    Writer = new LameMP3FileWriter(ExportFolder + @"\" + titleSongName + ".mp3", waveIn.WaveFormat, BitRate);
    waveIn.StartRecording();
    //Need The Pause Here
    StopIt();
}

void StopIt()
{
    // while (StopRecording == true) { }
    waveIn.StopRecording();
    Writer.Flush();
    waveIn.Dispose();
    Writer.Dispose();
    Tagger();
}

static void waveIn_RecordingStopped(object sender, StoppedEventArgs e)
{
    // signal that recording has finished
    stopRecording = true;
}

static void waveIn_DataAvailable(object sender, WaveInEventArgs e)
{
    // write recorded data to MP3 writer
    if (Writer != null)
        Writer.Write(e.Buffer, 0, e.BytesRecorded);
}

【问题讨论】:

  • 你为什么不能在waveIn_RecordingStopped中直接调用StopIt()
  • syntax 是什么意思?
  • @YeldarKurmangaliyev waveIn_RecordingStopped rasies 时 StopIt() 被调用(提高 waveIn_DataAvailable 将数据刷新到文件)
  • @VarandVartanian StopIt 将触发 waveIn_RecordingStoppedwaveIn_RecordingStopped 将变为 stopRecording = true。当stopRecording = true 时,它应该调用StopIt。看起来有一个循环,或者我误解了这个流程中的某些内容:)
  • @PeterBruins 在调用StopIt() 之前需要暂停(直到bool StopRecording 翻转)而不停止整个线程进程,因为如果它停止,录制也会停止。

标签: c# multithreading naudio


【解决方案1】:

你这么说:

  • StopIt 将触发 waveIn_RecordingStopped
  • waveIn_RecordingStopped 将使stopRecording = true
  • stopRecording = true 时应该调用StopIt

看起来有一个循环,或者我误解了这个流程中的某些内容:)

无论如何,如果你需要等待stopRecording变成true,你可以这样实现你的方法:

private async void Recorder()
{
    waveIn = new WasapiLoopbackCapture();
    waveIn.DataAvailable += waveIn_DataAvailable;
    waveIn.RecordingStopped += waveIn_RecordingStopped;
    Writer = new LameMP3FileWriter(ExportFolder + @"\" + titleSongName + ".mp3", waveIn.WaveFormat, BitRate);
    waveIn.StartRecording();

    while (!stopRecording)
    {
        await Task.Delay(250);
    }

    waveIn.StopRecording();
    Writer.Flush();
    waveIn.Dispose();
    Writer.Dispose();
    Tagger();
}

它将轮询直到stopRecording 变为true,而不会阻塞您的线程并导致while (stopRecording) { } 会出现的问题。

但是,如果这一切都发生在基于事件的系统中,那么使用事件是一个好主意。您的stopRecording 会在发生某些事情并且您需要立即处理时翻转 - 例如,当用户单击“停止”按钮时,您可以调用StopIt() 而不是“翻转stopRecording”。

【讨论】:

    最近更新 更多