는 귀하의 요구 사항 인 경우 : 사운드를 재생
- 시작 버튼을 누른 후 화면에 경과 시간을 표시하는 타이머를 시작합니다.
- 현재 타이머를 중지하고 마지막 값을 화면에 남겨 두는 중지 버튼.
- Windows Forms에서 구현됩니다.
다음 코드는 위의 요구 사항을 수행하는 방법에 대한 기본적인 예입니다. SoundPlayer의 PlaySync 메서드, BackgroundWorker (레이블의 값을 경과 된 초로 업데이트) 및 실제로 경과 시간을 기록하는 Stopwatch를 활용합니다. 이 작업을 수행하는 가장 좋은 방법은 아니지만 시작점을 제공해야합니다.
레이블을 작성한 스레드 (일반적으로 UI 스레드)와 다른 스레드에서 Label을 업데이트 할 수 없다는 점에 유의해야합니다. 따라서 다른 스레드에서 레이블 텍스트를 업데이트하려는 경우 레이블 .Invoke 메서드를 사용해야합니다 (아래 코드의 ThreadSafeUpdateLabel 메서드 참조).
이 코드는 누군가가 시작 버튼을 스팸 클릭 (클릭 한 번만 소리를냅니다)하고 시작 버튼을 클릭 할 때 UI가 정지되는 상황을 고려하지 않습니다. 연주 할 소리. 코드의 자연스러운 확장으로 이러한 문제를 해결할 것입니다.
어쨌든, 코드에 :
private Stopwatch _timer = new Stopwatch();
private BackgroundWorker _worker;
private void btnStop_Click(object sender, EventArgs e)
{
CancelExistingBackgroundWorker();
_timer.Stop();
}
private void btnStart_Click(object sender, EventArgs e)
{
CancelExistingBackgroundWorker();
_timer.Reset();
UpdateLabel(0);
_worker = new BackgroundWorker() { WorkerSupportsCancellation = true };
_worker.DoWork += (a, b) =>
{
while (true)
{
if ((a as BackgroundWorker).CancellationPending) return;
ThreadSafeUpdateLabel();
Thread.Sleep(100);
}
};
var soundPlayer = new SoundPlayer("wavfile.wav");
soundPlayer.PlaySync();
_timer.Start();
_worker.RunWorkerAsync();
}
private void ThreadSafeUpdateLabel()
{
if (lblElapsed.InvokeRequired)
{
lblElapsed.Invoke(new Action(() => ThreadSafeUpdateLabel()));
}
else
{
UpdateLabel(_timer.Elapsed.TotalSeconds);
}
}
private void UpdateLabel(double seconds)
{
lblElapsed.Text = seconds.ToString();
}
private void CancelExistingBackgroundWorker()
{
if (_worker != null)
{
_worker.CancelAsync();
_worker.Dispose();
}
}
좋아,하지만 귀하의 질문은 무엇인가? –
타이머가 시작되기를 원하지 않는다는 사실을 잊어 버렸습니다. 어떤 제안 ??? – user3029389
'Stopwatch'가 시작되지 않았다는 것을 어떻게 알 수 있습니까?'sw.IsRunning = false'와'sw.Elapsed = TimeSpan.Zero'입니까? –