gpt4 book ai didi

C# 任务 - 我是否遇到句柄数量的可疑增加

转载 作者:行者123 更新时间:2023-11-30 12:59:08 25 4
gpt4 key购买 nike

我正在尝试使用 Tasks (.NET 4.5),并且遇到了越来越多的句柄(在任务管理器中)。我有一个类使用 MediaPlayer 类(System.Windows.Media 命名空间)对音频文件进行简单的播放/停止。我有第二个类包装它并公开同步/异步播放。一切正常,功能正常,但看到任务管理器中的句柄数量增加,这让我很担心……我是不是做错了什么?

重要说明:如果我评论我们的“await Task.Delay(1000);” --> 然后一切正常,没有观察到泄漏...怎么会呢??

public partial class Form1 : Form
{
AudioActions syncAction = new AudioActions(@"c:\1.wav", false);
AudioActions asyncAction = new AudioActions(@"c:\1.wav", true);

public Form1()
{
InitializeComponent();
}

private async void syncPlayback(object sender, EventArgs e)
{
for (int i = 0; i < 10; i++)
{
await syncAction.Start();
}
}

private async void asyncPlayback(object sender, EventArgs e)
{
for (int i = 0; i < 100; i++)
{
await asyncAction.Start();
await Task.Delay(100); //remove this line and all is fine!!!!
asyncAction.Stop();
}
Console.WriteLine("done");
}
}

public class AudioActions
{
private Audio audio = null;
private TaskCompletionSource<bool> tcs = null;
private string pathToWaveFile;
private bool async;

public AudioActions(string pathToWaveFile, bool async)
{
this.pathToWaveFile=pathToWaveFile;
this.async=async;
}

public Task Start()
{
tcs = new TaskCompletionSource<bool>();
audio = new Audio();
audio.mediaPlayerPlaybackStoppedEvent += Audio_wmPlaybackStopped;

if (async)
tcs.TrySetResult(true); //since its async operation, lets return immediately and free the task from waiting

audio.PlayAudioFileInMediaPlayer(pathToWaveFile);
return tcs.Task;
}

private void Audio_wmPlaybackStopped()
{
audio.mediaPlayerPlaybackStoppedEvent -= Audio_wmPlaybackStopped;
tcs.TrySetResult(true); //playback stopped. Lets free the task from waiting
}

public void Stop()
{
audio.StopAudioFilePlaybackInMediaPlayer();
}
}

public class Audio
{
MediaPlayer mediaPlayer = null;

public delegate void MediaPlayerPlaybackStoppedDelegate();
public event MediaPlayerPlaybackStoppedDelegate mediaPlayerPlaybackStoppedEvent;

public void PlayAudioFileInMediaPlayer(string pathToWavFile)
{
mediaPlayer = new MediaPlayer();
mediaPlayer.MediaEnded += mediaPlayer_MediaEnded;
mediaPlayer.Open(new Uri(pathToWavFile));
mediaPlayer.Play();
}

void mediaPlayer_MediaEnded(object sender, EventArgs e)
{
mediaPlayerPlaybackStoppedEvent.Invoke();
MediaPlayer mediaPlayer = (MediaPlayer)sender;
mediaPlayer.MediaEnded -= mediaPlayer_MediaEnded;
mediaPlayer.Close();
mediaPlayer = null;
}

public void StopAudioFilePlaybackInMediaPlayer()
{
mediaPlayer.Stop();
mediaPlayer.Close();
mediaPlayer = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}

添加剥离代码:

private async void asyncPlayback(object sender, EventArgs e)
{
AudioActions asyncAction = new AudioActions();
for (int i = 0; i < 100; i++)
{
await asyncAction.Start();
await Task.Delay(1000); //remove this line and all is fine!!!!
asyncAction.Stop();
}
}

public class AudioActions
{
private Audio audio = null;
private TaskCompletionSource<bool> tcs = null;

public Task Start()
{
tcs = new TaskCompletionSource<bool>();
audio = new Audio();
tcs.TrySetResult(true); //since its async operation, lets return immediately and free the task from waiting

audio.PlayAudioFileInMediaPlayer(@"c:\1.wav");
return tcs.Task;
}

public void Stop()
{
audio.StopAudioFilePlaybackInMediaPlayer();
}
}

public class Audio
{
MediaPlayer mediaPlayer = null;

public void PlayAudioFileInMediaPlayer(string pathToWavFile)
{
mediaPlayer = new MediaPlayer();
mediaPlayer.Open(new Uri(pathToWavFile));
mediaPlayer.Play();
}

public void StopAudioFilePlaybackInMediaPlayer()
{
mediaPlayer.Stop();
mediaPlayer.Close();
mediaPlayer = null;
GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
}
}

修改类解决问题:

public class Audio
{
public delegate void NaudioPlaybackStoppedDelegate();
public event NaudioPlaybackStoppedDelegate naudioPlaybackStoppedEvent;

private WaveOut player = null;

public void PlayAudioFileUsingNaudio(string pathToWavFile)
{
player = new WaveOut();
AudioFileReader waveFileReader = new AudioFileReader(pathToWavFile);
player.Init(waveFileReader);
player.PlaybackStopped += NAudio_Stopped;
player.Play();
}

private void NAudio_Stopped(object sender, StoppedEventArgs e)
{
player.PlaybackStopped -= NAudio_Stopped;
if (naudioPlaybackStoppedEvent!=null)
naudioPlaybackStoppedEvent.Invoke();
player.Dispose();
}

public void StopAudioFilePlaybackInNaudio()
{
player.Stop();
}
}

最佳答案

用 NAudio 3rd party 替换 MediaPlayer 解决了这个问题。

public class Audio
{
public delegate void NaudioPlaybackStoppedDelegate();
public event NaudioPlaybackStoppedDelegate naudioPlaybackStoppedEvent;

private WaveOut player = null;

public void PlayAudioFileUsingNaudio(string pathToWavFile)
{
player = new WaveOut();
AudioFileReader waveFileReader = new AudioFileReader(pathToWavFile);
player.Init(waveFileReader);
player.PlaybackStopped += NAudio_Stopped;
player.Play();
}

private void NAudio_Stopped(object sender, StoppedEventArgs e)
{
player.PlaybackStopped -= NAudio_Stopped;
if (naudioPlaybackStoppedEvent!=null)
naudioPlaybackStoppedEvent.Invoke();
player.Dispose();
}

public void StopAudioFilePlaybackInNaudio()
{
player.Stop();
}
}

关于C# 任务 - 我是否遇到句柄数量的可疑增加,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26990511/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com