Dou*_*oug 6 c# multithreading background save
我有一台相机,我正在将图像实时读入阵列.我正在将一些算法应用于图像并显示它.然后我得到下一个图像并显示它.所以我将图像从相机流式传输到显示器.但是,我也希望在显示图像后将图像保存到硬盘.我尝试使用主线程,但一切都放慢了太多.然后我尝试使用ThreadPool(参见下面的代码).这不会减慢显示速度,但我发现图像没有正确保存.看起来它们不是预期的顺序,并且在保存了大约50个图像之后,后续图像数据看起来很乱.我猜太多线程正在启动.
有一个更好的方法吗?我想我只需要一个线程来保存图像.也许是某种顺序保存每个图像的队列.只要它在后台完成并且不会减慢显示速度.如果有人可以发布一个非常棒的代码片段.
short[] image1 = new short[20000];
while(streaming)
{
ReadImageFromCamera(ref image1)
ImageData data;
data.fileName = imageNumber;
data.image = image1;
ThreadPool.QueueUserWorkItem(WriteImageToFile, data); // Send the writes to the queue
}
private void WriteImageToFile(object imageData) {
try {
ImageData data = (ImageData)imageData;
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter bf = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
string fName = myDirectory + @"/" + Convert.ToString(data.fileName) + @".spe";
using (Stream myStream = new FileStream(fName, FileMode.Create)) {
bf.Serialize(myStream, data.image);
}
}
catch (Exception) { }
}
Run Code Online (Sandbox Code Playgroud)
我认为你应该避免为每个特定的图像开始一个新的线程.由于您只有一个硬盘驱动器并将所有文件存储到单个目录中,因此您应该只使用一个磁盘写入程序线程.然后我建议使用一些并发队列将作业从相机线程传输到磁盘写入器线程.我没有显示"代码片段",因为这不是一个可以在几行代码中以高质量编写的东西.
此外,您肯定必须在某处为每个图像添加"新短[20000]",否则在将其保存到磁盘之前会被下一个图像覆盖.
此外,我希望在主线程中写入文件就足够了,因为在将数据写入磁盘时,Windows会自动使用并发技术(主要是磁盘缓存).您确定您的硬件足够快以实时写入所有这些数据吗?
处理线程时,顺序不再由您控制。线程池可以选择按照它喜欢的任何顺序来调度线程。如果您需要事情按特定顺序依次发生,那么线程无论如何都没有多大意义。
关于损坏的图像,看起来该short[] image1实例正在被传递。目前尚不清楚内部发生了什么ReadImageFromCamera,但由于您将预初始化的数组传递给其中,该方法很可能会使用该数组并简单地将数据复制到其中(即使关键字ref表明它可能会创建一个全新的数组实例并且而是分配它)。然后将该数组实例传递给WriteImageToFile单独的线程。
与此同时,您同时获得下一张图像。现在您有一个场景,ReadImageFromCamera可能会在将数据存储在磁盘上的同时将数据写入阵列WriteImageToFile。那里有你损坏的图像。这可以通过将新的数组实例传递给来避免WriteImageToFile:
ReadImageFromCamera(ref image1)
ImageData data;
data.fileName = imageNumber;
data.image = (short[])image1.Clone(); // create a new array instance, so that
// the next call to ReadImageFromCamera
// will not corrupt the data
ThreadPool.QueueUserWorkItem(WriteImageToFile, data);
Run Code Online (Sandbox Code Playgroud)
不过,正如 Al Kepp 所提到的,由于您只有一个硬盘驱动器,因此启动多个线程可能不是您的最佳选择。您可以考虑使用一个长时间运行的单独线程来在磁盘上存储数据,并将图像放入某种队列中,存储线程从磁盘中获取数据并将其写入磁盘。这带来了一系列处理并发性、限制队列大小等问题。
| 归档时间: |
|
| 查看次数: |
3258 次 |
| 最近记录: |