我碰壁了,来到这里希望你们能帮我解决以下问题:
我正在设计一个 wp7 应用程序,其中我的声音会定期(每 700 毫秒)触发。我希望这些声音在 UI 线程以外的另一个线程上播放。因此,我不能使用dispatch timer
因为在此期间,当这些声音触发时,UI 线程将被大量使用。
在研究这个问题时,我用Thread.Sleep(700)
命令做了一个backgroundworker
。这有效,但正如人们所期望的那样,发射声音可能需要超过 700 毫秒的时间。所以有时我会听到延迟。
所以我转向你们 - 我怎样才能在backgroundworker
或其他线程中每700毫秒发出一次声音?Timer
是一个明智的主意吗?
以下是一些代码可以更好地说明:
private void RunBackgroundWorker()
{
backgroundWorker = new BackgroundWorker ();
backgroundWorker.WorkerSupportsCancellation = true;
backgroundWorker.DoWork += new DoWorkEventHandler(StartSounds);
backgroundWorker.RunWorkerAsync();
}
public void StartSounds(object sender, EventArgs e)
{
for (currentsoundchoice = 0; currentsoundchoice <= max; currentsoundchoice ++)
{
if (backgroundWorker.CancellationPending == true)
{
backgroundWorker.CancelAsync();
currentsoundchoice = max + 1; //just to ensure it stops.
}
else
{
Time_Tick();
if (max == 12)
currentsoundchoice = -1; //repeats the loop when it reaches max.
}
}
}
void Time_Tick()
{
Thread.Sleep(700);
FrameworkDispatcher.Update();
switch (sounds)
case 0: //code
break;
// ETC, So forth.......
}
我听说使用计时器也是一个很好的方法,但是是否可以在后台工作线程中运行计时器,如果是这样,它将如何构建?更重要的是,它是否允许我尽可能接近我想要的 700 毫秒的射击时间而没有任何可听见的延迟?
谢谢。
BackgroundWorker
在这里是错误的选择。它旨在允许您在后台线程上执行昂贵的工作,然后将结果同步回 UI。您不需要任何同步。此外,您需要定期进行工作 - 而不是一次性任务。
Timer
会更适合。它将允许您每 700 毫秒运行一次逻辑,并删除当前代码中令人讨厌的Thread.Sleep()
调用。Timer
将像BackgroundWorker
一样使用后台线程。
但请注意,它只能保证它不会在 700 毫秒之前运行。例如,如果您绝对在锤击设备,它可能很难定期运行您的代码,并且您可能会注意到延迟。