미디어 플레이어 (Media.MediaPlayer() 클래스 사용)를 만들려고합니다.이 때문에 스레드를 사용하여 OpenFileDialog를 사용하여 사용자가로드 한 노래를 처리하고 있습니다. 나는 과정 노래 시작하려면 다음 코드를 사용하고 있습니다 :Open MediaPlayer - 스레드에서 처리되지 않은 이벤트
public static List<MediaFile> MediaList = new List<MediaFile>();
public static Queue<String> MediaFilesQueue = new Queue<String>();
public static void AddMediaFilesToMediaList()
{
String pathToFile;
while (MediaFilesQueue.Count > 0)
// all the files are loaded into the Queue before processing
{
pathToFile = MediaFilesQueue.Dequeue();
MediaData.MediaList.Add(new MediaFile(pathToFile));
MediaFileCreator mfCreator =
new MediaFileCreator(MediaData.MediaList.Count - 1);
mfCreator.CreateNewMediaFile();
}
}
을 그리고 이것은 MediaFileCreator 클래스입니다 :
public class MediaFileCreator
{
private int IndexOfMediaFileCurrentlyProcessed;
public MediaFileCreator(int idx)
{
IndexOfMediaFileCurrentlyProcessed = idx;
}
public void CreateNewMediaFile()
{
var indexOfMediaFileCurrentlyProcessed = IndexOfMediaFileCurrentlyProcessed;
var tempMediaFile = MediaData.MediaList[indexOfMediaFileCurrentlyProcessed];
var tempMediaPlayer = new MediaPlayer();
var waitHandle = new AutoResetEvent(false);
//EventHandler eventHandler = delegate(object sender, EventArgs args)
//{
// waitHandle.Set();
//};
tempMediaPlayer.MediaOpened += (sender, args) => waitHandle.Set();
tempMediaPlayer.Open(new Uri(tempMediaFile.PathToFile));
waitHandle.WaitOne();
//while (!tempMediaPlayer.NaturalDuration.HasTimeSpan)
//{
// Thread.Sleep(100);
//}
var tempTimeSpan = tempMediaPlayer.NaturalDuration.TimeSpan;
var hasVideo = tempMediaPlayer.HasVideo;
var hasAudio = tempMediaPlayer.HasAudio;
MediaData.MediaList[indexOfMediaFileCurrentlyProcessed].HasVideo = hasVideo;
MediaData.MediaList[indexOfMediaFileCurrentlyProcessed].HasAudio = hasAudio;
MediaData.MediaList[indexOfMediaFileCurrentlyProcessed].TimeSpanOfMediaFile
= tempTimeSpan;
}
그리고 이것은 미디어 파일 클래스입니다 :
public class MediaFile
{
public bool HasAudio = false;
public bool HasVideo = false;
public TimeSpan TimeSpanOfMediaFile;
public String PathToFile = null;
public MediaFile(String pathToFile)
{
PathToFile = pathToFile;
}
}
제 문제는 프로그램이 waitHandle.WaitOne();
에 멈추고 그 프로그램을 실행하려고하는 것입니다. 다시 계속해서. 첫 번째 주석 처리 된 섹션의 이벤트 핸들러를 Open 이벤트에 연결하여 다른 변형을 시도했지만 결과는 같았습니다. waitHandle.Set();
이 실행되지 않으며 waitHandle의 값은 항상 false입니다. 필자가 관리 할 수 있었던 유일한 옵션은 두 번째 주석 처리 된 섹션의 솔루션입니다. 파일이 완전히로드 될 때까지 Thread.Sleep을 사용하여 스레드를 차단합니다 (예 : TimeSpan이 초기화 될 때 파일이로드 됨). 이는 내 응용 프로그램의 시간 손실과 성능 저하입니다. 문제는 분명히 이벤트 자체가 아닙니다. 이벤트가 주 스레드에서 실행되는 경우 트리거되기 때문에 (AddMediaFilesToMediaList() 메서드는 백그라운드 스레드에 요소가 있음을 감지하면 새 스레드 내부에서 메서드를 시작하는 BackgroundWorker 스레드에서 호출됩니다. Queue : AddMediaFilesToMediaList() 스레드는 new Thread()
으로 생성됩니다. 분명히 TimeSpan이 초기화되어 있기 때문에 파일이로드되고 있습니다. 나는 waitHandle 같은 것을 사용하여 응용 프로그램을 만들고 싶습니다. Thread.Sleep()을 사용하고 싶지 않습니다. 추한 것이기 때문에 많은 응용 프로그램을로드하려고 할 때 응용 프로그램에 메모리 누수가 있습니다. 1.2GB 이상의 메모리가 필요하고 오류 (OutOfMemory)가 발생합니다. - 2048 곡을로드하려고했습니다.) 그리고 Thread.Sleep() 때문에 그럴 수 있다고 생각합니다. 그렇지 않은 경우에도 Thread.Sleep() 문제없이 디버깅하는 것이 훨씬 쉽습니다.
어떻게하면 waitHandle을 작동시킬 수 있습니까? waitHandle.Set();
을 실행하려면 어떻게해야합니까? 그리고 과도한 메모리 사용량이 어디서 올 수 있었는지에 대한 생각이 있다면 큰 도움이 될 것입니다! (나는 개인적으로 그것이 Thread.Sleep()의 잘못이라고 믿지만 그것을 제거하는 방법을 모른다.)
편집 : MediaFileCreator 객체를 사용하는 이유는 처음에 미디어 파일을 처리하기 위해 2에서 4 개의 스레드 풀을 사용하기를 원했지만 동일한 문제가있어서 ThreadPool을 제거하고 위의 코드를 게시했지만 동일한 문제가 발생했습니다.
편집 : 두 번째 스레드를 사용하여 이벤트를 기다릴 수 있었지만 (지금은 가장 깨끗한 코드가 아니지만 올바르게 만들 것입니다.)
public class MediaFileCreator
{
private AutoResetEvent openedEvent = new AutoResetEvent(false);
public MediaFile CreateNewMediaFile(string filename)
{
var mFile = new MediaFile(filename);
var thread = new Thread(WaitForEvent);
const int maxTimeToWait = 2000;
openedEvent.Reset();
thread.Start(mFile);
var mediaPlayer = new MediaPlayer();
mediaPlayer.Open(new Uri(mFile.PathToFile));
openedEvent.WaitOne(maxTimeToWait);
var fromThread = Dispatcher.FromThread(Thread.CurrentThread);
if (fromThread != null) fromThread.InvokeShutdown();
return mFile;
}
private void WaitForEvent(object context)
{
var mFile = (MediaFile)context;
var mediaPlayer = new MediaPlayer();
mediaPlayer.MediaOpened +=
delegate
{
if (mediaPlayer.NaturalDuration.HasTimeSpan)
mFile.TimeSpanOfMediaFile = mediaPlayer.NaturalDuration.TimeSpan;
mFile.HasAudio = mediaPlayer.HasAudio;
mFile.HasVideo = mediaPlayer.HasVideo;
mFile.Success = true;
mediaPlayer.Close();
openedEvent.Set();
};
mediaPlayer.MediaFailed +=
delegate
{
mFile.Failure = true;
mediaPlayer.Close();
openedEvent.Set();
};
mediaPlayer.Open(new Uri(mFile.PathToFile));
Dispatcher.Run();
}
}
완성 된 답변을 참조하십시오. –