我正在写一个WPF项目来模拟不同结构(如建筑物)中的视频显示。
在这个项目中,我使用了一个特殊类型的二进制视频与bin扩展,其中的颜色存储为红色,绿色和蓝色。
我有两个方法,第一个是**“ReadDisplayBinFrames”,它有两个任务,阅读bin视频并将其显示在结构上。当然,由于这两个任务是异步的**,因此我将该方法定义为async。
public async Task ReadDisplayBinFrames(Product product, bool PlayMode)
{
BinFile.SetPlayMode(PlayMode);
int currentFrameNumber = 0;
for (int i = 0; BinFile.IsPlayMode == true; i++)
{
for (currentFrameNumber = (int)product.LastFrameRead; currentFrameNumber <= product.BinFiles.TotalGame; currentFrameNumber++)
{
await Task.Run(() =>
{
product.BinFiles.GetSphereColorFromBin(product.BinFiles.Read(currentFrameNumber), product.Wiring);
product.LastFrameRead = currentFrameNumber;
Debug.WriteLine($"LastFrameRead {product.LastFrameRead}");
product.Wiring.SetSphereColor(product.DelayPlay);
});
if (currentFrameNumber >= product.BinFiles.TotalGame)
{
product.LastFrameRead = 0;
}
if (animPlayingMode == AnimPlayingMode.SerialAsync)
{
BinFile.SetPlayMode(false);
}
}
}
}
由于我有一个结构列表,并且我需要能够在同时在每个结构上显示视频,因此我定义了一个名为**“PlayBin”**的方法。
private async void PlayBin()
{
InitBinList();
for (int i = 0; i < Products.Count; i++)
{
if (animPlayingMode == AnimPlayingMode.ParallelSynchronous)
{
Parallel.Invoke(async () =>
{
await ReadDisplayBinFrames(Products[i], true);
Debug.WriteLine($"LedProducts Count: {Products[i].LastFrameRead} of Product {i}");
});
}
else
{
await ReadDisplayBinFrames(Products[i], true);
Debug.WriteLine($"LedProducts Count: {Products[i].LastFrameRead} of Product {i}");
}
}
}
当我在一个结构上显示视频时,它可以毫无问题地显示,但当我增加结构的数量(例如,6个)时,与只有一个结构的情况相比,播放速度略有下降,过了一会儿,协调性就丢失了。每个结构前进或后退几帧。
Videos Of Software Performance
1条答案
按热度按时间mzaanser1#
Parallel.Invoke
不支援异步方法。它必须执行简单的void委派(例如Action<T>
)。这表示执行的委派永远会同步执行。您的代码是一个很好的例子,说明了为什么将async lambda作为
Action
的参数传递会引入潜在的bug:因为委托的调用方需要一个Action
,所以它不会对async
方法执行await
。async
方法将返回Task
,并且调用方将立即继续(而不是等待此Task
)。在您的情况下,
Parallel.Invoke
将在async
方法运行完成 * 之前 * 继续。这将导致删除async
上下文和意外行为。另请注意,
async
方法必须始终返回Task
或Task<T>
(除非该方法是事件处理程序)。应该始终使用
Task.WhenAll
而不是Parallel.Invoke
来执行许多异步方法,并等待它们全部完成: