gpt4 book ai didi

c# - 使用多线程提高速度

转载 作者:太空宇宙 更新时间:2023-11-03 12:13:25 26 4
gpt4 key购买 nike

我有一个名为 PlaylistView 的 CustomControl。它在带有名称和缩略图的播放列表中显示元素。 DisplayPlaylist 方法确保启动一个线程,在该线程中逐个添加各个元素并读取缩略图(第 30 帧):

public void DisplayPlaylist(Playlist playlist)
{
Thread thread = new Thread(() => DisplayElements(playlist));
thread.Start();
}

private void DisplayElements(Playlist playlist)
{
for (int i = 0; i < playlist.elements.Count; i++)
DisplayElement(playlist.elements[i], i);
}

private void DisplayElement(IPlayable element, int index)
{
VideoSelect videoSelect = null;

if (element is Audio)
//
else if (element is Video)
videoSelect = new VideoSelect(index, element.name, GetThumbnail(element.path, SystemData.thumbnailFrame));

videoSelect.Location = GetElementsPosition(index);

panel_List.BeginInvoke(new Action(() =>
{
panel_List.Controls.Add(videoSelect);
}));
}

private Bitmap GetThumbnail(string path, int frame)
{
VideoFileReader reader = new VideoFileReader();
try
{
reader.Open(path);

for (int i = 1; i < frame; i++)
reader.ReadVideoFrame();

return reader.ReadVideoFrame();
}
catch
{
return null;
}
}

但是有个问题。

它太慢了(大约 10 个元素/秒)。播放列表长度为 614,您将不得不等待一分多钟才能显示所有内容。每次更改播放列表(例如添加或删除项目)时,程序都会从​​新项目开始。添加 2 个或更多会使它变得更加复杂。

我现在有了使用多线程的方法,并且为此使用的线程数由用户指定(1 到最大 10)。目前代码中的实现是这样的(与之前发布的代码相比,仅更改了部分)

public void DisplayPlaylist(Playlist playlist)
{
for (int i = 0; i < SystemData.usedDisplayingThreads; i++)
{
Thread thread = new Thread(() => DisplayElements(playlist, i));
thread.Start();
}
}

private void DisplayElements(Playlist playlist, int startIndex)
{
for (int i = startIndex; i < playlist.elements.Count; i += SystemData.usedDisplayingThreads)
DisplayElement(playlist.elements[i], i);
}

问题是现在 GetThumbnail 函数经常返回 null,所以会发生错误。此外,通常会抛出 System.AccessViolationException

在我看来,这是因为存在多个同时处于事件状态的 VideoFileReader。但是,我不知道究竟是什么触发了这个问题,所以我无法提供任何解决方案。也许您知道实际触发器是什么以及如何解决问题,或者您可能还知道其他提高速度的方法,这些方法可能更优雅。

最佳答案

我将从记录 GetThumbnail 方法中引发的异常开始。您的代码将其隐藏并返回 null。更改为 catch (Exception exc),在日志中写入异常详细信息或至少在调试器中进行评估。这可以给一个提示。

此外,我非常确定您的 VideoFileReader 实例是 IDisposable 的,因此您必须通过调用 reader.Close() 来处理它们。也许以前的实例没有被处理掉,而你正试图多次打开同一个文件。

更新:视频帧也必须处理。如果读取器引用位图并防止处置,您可能需要复制位图。

关于c# - 使用多线程提高速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50927402/

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