项目详细信息:在这个WPF项目中,视频显示在一些结构上。实际上,它是一种模拟器,模拟视频在安装在结构或建筑物上的LED上的显示。
private async Task PlayBinAsync()
{
InitBinList();
if (animPlayingMode == AnimPlayingMode.ParallelSynchronous)
{
List<Task> runningTasks = new List<Task>();
Coordinator.Clear();
for (int i = 0; i < Products.Count; i++)
{
Coordinator.Add(0);
Task runningTask = ReadDisplayBinFrames(Products[i], true);
runningTasks.Add(runningTask);
#if DEBUG
Debug.WriteLine($"LedProducts Count: {Products[i].LastFrameRead} of Product {i}");
#endif
}
await Task.WhenAll(runningTasks);
}
}
public async Task ReadDisplayBinFrames(Product product, bool PlayMode)
{
BinFile.SetPlayMode(PlayMode);
while (BinFile.IsPlayMode)
{
for (int currentFrameNumber = product.LastFrameRead; currentFrameNumber <= product.BinFiles.TotalGame; currentFrameNumber++)
{
await Task.Run(() =>
{
product.BinFiles.GetSphereColorFromBin(product.BinFiles.GetFrame(currentFrameNumber), product.Wiring);
product.LastFrameRead = currentFrameNumber;
#if DEBUG
Debug.WriteLine($"LastFrameRead {product.LastFrameRead}");
#endif
product.Wiring.SetSphereColor(product.DelayPlay);
});
Coordinator[product.ProductId] += 1;
await AllowPlayAsync(Coordinator);
if (currentFrameNumber >= product.BinFiles.TotalGame)
{
product.LastFrameRead = 0;
}
if (animPlayingMode == AnimPlayingMode.SerialAsync)
{
BinFile.SetPlayMode(false);
}
}
}
}
private async Task AllowPlayAsync(List<int> input)
{
if (input.All(o => o == input[0]))
{
signal.Release();
}
else
{
await signal.WaitAsync();
}
}
List<int> Coordinator = new List<int>();
private SemaphoreSlim signal = new SemaphoreSlim(0, 1);
项目要求:
1-我希望所有的结构或建筑物运行的视频一致,甚至没有一个帧落后或一个帧前进。2-该项目应连续运行,不应停止播放视频,直到它停止。
为了使这些帧在结构上一起执行,我将执行的帧数存储在一个列表中,并使用AllowPlayAsync方法等待所有帧相遇并成为一个帧。
但不幸的是,它不能正常工作!
2条答案
按热度按时间56lgkhnf1#
我不认为信号量是正确的解决办法。
如果您有一个进程需要显示多个同步图像,只需使用一个线程从每个源中选取图像,并将帧列表发送到UI线程。
您可以为每个视频流使用BlockingCollections。即,为每个视频流使用一个任务/线程来生成帧,并使用一个相当低的“上限”来阻止有足够缓冲区的生成线程。
然后,单个线程将从每个集合中获取一个图像。如果图像还不可用,则线程将阻塞,直到图像可用为止。一旦从每个集合中获取了图像,就将所有图像发送到UI线程以进行更新。
我不是WPFMaven,但我认为wpf有一个单独的渲染线程,所以当主线程更新图像时,可能会发生渲染。如果你需要更好的保证,你可能必须将所有图像合并成一个大图像,或者做一些其他操作系统的魔术来阻止渲染线程。
rsaldnfx2#
经过大量的搜索,我修改和优化了前面的代码如下:此代码运行良好并且准确,但是如果我希望其中一个产品单独工作或与其他产品分开工作,它将无法工作,并且会立即与其他产品协调。我决定使用**“Products list”而不是“Coordinator list”,但是由于未知原因,在运行AllowPlayAsync**方法几帧后,它会停留在等待模式中,并且不会从该模式中退出。