我正在研究WinRT C#应用程序。我有一个每秒提高15-30次的事件。这个事件为我提供了一个字节数组参数(它实际上是byte []中的一个图像):
void FrameArrived(object sender, byte[] pixels)
{
// 1. Create a bitmap and render it on an <Image> element (UI thread).
DisplayBitmap(pixels);
// 2. Pass the byte array to a method for video recording.
RecordBitmap(pixels);
}
DisplayBitmap
和RecordBitmap
都是繁重的进程,用户界面变慢。
如果我只调用其中一种方法,一切正常。
请记住,此事件每秒增加15-30次。
我需要一种方法来并行运行这两种方法。我尝试过使用Dispatcher,Parallel.Invoke和ThreadPool,结果不佳。
提前谢谢。
答案 0 :(得分:0)
如果你需要按顺序记录像素数组,那么你不能只为每个函数调用启动一个新线程,因为不能保证线程按顺序运行。我们的想法是尽可能快地将项目推送到列表中,然后让另一个线程以自己的速率处理项目。这只会对代码的录制部分有所帮助,如果你试图渲染的图像比UI线程可以处理的更多,那么这就是另一个问题。
void FrameArrived(object sender, byte[] pixels)
{
//push pixels into list
lock (_pixelList)
{
_pixelList.Add(pixels);
}
_waitHandle.Set();
// 1. Create a bitmap and render it on an <Image> element (UI thread).
DisplayBitmap(pixels);
// 2. Pass the byte array to a method for video recording.
//RecordBitmap(pixels);
}
AutoResetEvent _waitHandle = new AutoResetEvent(false);
List<byte[]> _pixelList = new List<byte[]>();
bool _stop = false;
void StartProcessPixelsThread()
{
Task.Run(() =>
{
while (!_stop)
{
_waitHandle.WaitOne();
while (true)
{
byte[] pixels;
lock (_pixelList)
{
if (_pixelList.Count > 0)
{
pixels = _pixelList[0];
_pixelList.RemoveAt(0);
}
else
{
break;
}
}
RecordBitmap(pixels);
}
}
});
}
void StopProcessPixelsThread()
{
_stop = true;
_waitHandle.Set();
}
答案 1 :(得分:0)
我终于使用ConcurrentQueue制作了它。它与@Jon提出的略有不同。再次感谢大家的帮助!
// Stores the frames coming from different threads.
ConcurrentQueue<byte[]> _queue = new ConcurrentQueue<byte[]>();
// Begins recording.
public void Start()
{
if (!IsRecording)
{
IsRecording = true;
}
Task.Run(() =>
{
while (IsRecording || _queue.Count > 0)
{
byte[] pixels;
if (_queue.TryDequeue(out pixels))
{
RecordBitmap(pixels);
}
}
});
}
// Stops recording.
public void Stop()
{
if (IsRecording)
{
IsRecording = false;
}
}
// Updates the frames (called from FrameArrived).
public void Update(byte[] pixels)
{
_queue.Enqueue(pixels);
}