gpt4 book ai didi

c# - 如何检查.NET BlockingCollection 状态并等待完成?

转载 作者:太空狗 更新时间:2023-10-30 00:31:47 26 4
gpt4 key购买 nike

我有一个 C# 工作线程,它使用 BlockingCollection 将一批相机位图保存到光盘中。它工作得很好,但我需要一个从主应用程序调用的方法,该方法会阻止执行,直到保存所有排队的位图(例如,参见消息结尾)。

整个类(class)看起来像:

namespace GrabGUI
{
struct SaveTask
{
public string fname;
public Bitmap bm;
}

class ImageWriter
{
private BlockingCollection<SaveTask> queue = new BlockingCollection<SaveTask>();

//resets when read
public string ErrorsOccurred;
private Thread writerthread;

public ImageWriter()
{
writerthread = new Thread(new ThreadStart(Writer));
writerthread.Start();
}


public void Stop()
{
queue.CompleteAdding();
}

public string WaitForIdleAndGetErrors()
{
//HOW TO WAIT FOR QUEUE TO GET PROCESSED?

return ErrorsOccurred;
}

public void AddImageToQueue(string filename, Bitmap bmap)
{
SaveTask t;
t.bm=bmap;
t.fname=filename;
queue.Add(t);
}

void Writer()
{
while (queue.IsCompleted==false)
{
try
{
SaveTask t = queue.Take();// blocks when the queue is empty
SaveBitmap(t.fname, t.bm);
}
catch (Exception e)
{
//comes here after called Stop
return;
}
}
}


private void SaveBitmap(string filename,Bitmap m_bitmap)
{
//saving code
}

}
}

并且在主应用中使用,例如:

ImageWriter w=new ImageWriter();

w.AddImageToQueue(fname,bitmap);//repeat many times
...

//wait until whole queue is completed and get possible errors that occurred
string errors=w.WaitForIdleAndGetErrors();

所以问题是如何实现对WaitForIdleAndGetErrors()的阻塞等待。有什么建议吗?

最佳答案

这里有一个非常简单的方法:

public string WaitForIdleAndGetErrors()
{
while (queue.IsCompleted == false )
{
System.Threading.Thread.Current.Sleep(100);
}

return ErrorsOccurred;
}

或者使用 ManualResetEventSlim:

声明新的实例变量:

ManualResetEventSlim _mre = new ManualResetEventSlim(false);

public string WaitForIdleAndGetErrors()
{
if (queue.IsCompleted == false )
{
_mre.Wait();
}

return ErrorsOccurred;
}

然后当您的队列完成时向 mre 发出信号。

_mre.Set();   // this will release any thread waiting.

最后,您需要在添加项目进行处理时Reset() _mre,这将导致任何Wait() 阻塞,直到_mre 发出信号(通过 Set())

需要考虑的事情

如果您使用 UI 线程调用它,那么所有 UI 交互都将被卡住,您最好使用 Timer 进行轮询或类似的东西,否则您的 UI 体验会很差。

但是,您可以使用 BackgroundWorker 触发整个过程,然后 Invoke UI 线程将在完成时处理的方法/事件。

关于c# - 如何检查.NET BlockingCollection 状态并等待完成?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22939646/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com