WinRT:同时运行两个共享资源的任务

时间:2014-05-08 21:52:23

标签: c# parallel-processing windows-runtime windows-store-apps

我正在研究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);
}

DisplayBitmapRecordBitmap都是繁重的进程,用户界面变慢。

如果我只调用其中一种方法,一切正常。

请记住,此事件每秒增加15-30次。

我需要一种方法来并行运行这两种方法。我尝试过使用Dispatcher,Parallel.Invoke和ThreadPool,结果不佳。

提前谢谢。

2 个答案:

答案 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);
}