当接收到硬件设备传来的数据队列时,比如拍到的一幅幅照片,需要按顺序调用识别模块时,就需要用队列来缓存调用的方法。示例代码如下:
bool isCanShiBie = true, isStartThread=true;
static Queue queue = new Queue(); // 创建一个线程安全的队列
private void button1_ClickAsync(object sender, EventArgs e)
{
if (isStartThread)
{
// 创建并启动一个消费者线程来处理队列中的任务
Thread consumerThread = new Thread(ProcessQueue);
consumerThread.Start();
isStartThread = false;
}
// 将任务添加到队列中
EnqueueTask(ShiBie);
//Thread td = new Thread(ShiBie);
//td.IsBackground = true;
//td.Start();
// ShiBie();
// 在线程中调用异步方法
// ThreadPool.QueueUserWorkItem( ShiBie, 1);
//Thread thread = new Thread(() =>
//{
// Task task = Task.Run(async () => await ShiBie()); // 使用Task.Run包装异步方法
// isCanShiBie = true; // int result = task.Result; // 等待异步操作完成并获取结果
// // Console.WriteLine(result); // 处理结果
//});
//thread.IsBackground = true;
//thread.Start();
}
static void EnqueueTask(Action task)
{
lock (queue)
{
queue.Enqueue(task);
}
}
bool isProcessQueue = true;
void ProcessQueue()
{
while (isProcessQueue)
{
Action task = null;
lock (queue)
{
if (queue.Count > 0&& isCanShiBie )
{
task = queue.Dequeue();
}
}
if (task != null)
{
isCanShiBie = false;
task();
}
Thread.Sleep(10);
}
}
string img_id = "20230608001";
int i = 0;
public class ResultWithError
{
public T Result { get; set; }
public byte[] Error { get; set; }
}
public async Task> CallCppDllAsync(IntPtr imgId, IntPtr image, int width, int height, int step)
{
try
{
return await Task.Run(() =>
{
byte[] error = new byte[1024 * 5];
int result = recogCell_mat_nopath(imgId, image, width, height, step, ref error[0]);
return new ResultWithError { Result = result, Error = error };
});
}
catch (Exception ex)
{
Loger loger = new Loger();
loger.WriteLog("recogCell_mat_nopath异常");
loger.WriteLog(ex.ToString());
return new ResultWithError { Result = -1, Error = null };
}
}
private async void ShiBie()
{
try
{
// byte[] error = new byte[1024 * 5];
int stride = 0;
Bitmap bmp = new Bitmap("C.jpg");
System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, bmp.Width, bmp.Height);
System.Drawing.Imaging.BitmapData bmpData = bmp.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, bmp.PixelFormat);
System.Drawing.Imaging.PixelFormat pf = bmp.PixelFormat;
if (pf == System.Drawing.Imaging.PixelFormat.Format32bppArgb)
{
stride = bmp.Width * 4;
}
else
{
stride = bmp.Width * 3;
}
i++;
// Image im = new Image(bmp.Width, bmp.Height, stride, (IntPtr)bmpData.Scan0);
img_id = img_id.Substring(0,10) + $"_{i}";
IntPtr ptrIn = Marshal.StringToHGlobalAnsi(img_id);
int result = 0;
// IntPtr ptrRet =(IntPtr) 0;
this.Invoke(new Action(() =>
{
//listboxInfo.
listboxInfo.AppendText(DateTime.Now.ToString("G")+" "+img_id + "开始--------------");
listboxInfo.AppendText("\r\n");
// 创建 Stopwatch 实例
}));
Stopwatch stopwatch = new Stopwatch();
// 启动计时器
stopwatch.Start();
isCanShiBie = false;
var resultT = await CallCppDllAsync(ptrIn, (IntPtr)bmpData.Scan0, bmp.Width, bmp.Height, 3);
result = resultT.Result;
byte[] error = resultT.Error;
isCanShiBie = true;
// result = recogCell_mat_nopath(ptrIn, (IntPtr)bmpData.Scan0, bmp.Width, bmp.Height, 3, ref error[0]);
stopwatch.Stop();
var s = "";
// DetectImage(im_ptr, size.Width, size.Height, step, ref error[0]);
s = Encoding.UTF8.GetString(error);
if (true||result ==0)
{
dynamic model = JObject.Parse(s);
this.Invoke(new Action(() =>
{
//listboxInfo.
// 获取经过的时间
TimeSpan elapsed = stopwatch.Elapsed;
listboxInfo.AppendText(DateTime.Now.ToString("G") + " " + model.img_id + $"结束---{elapsed.Seconds}s{elapsed.Milliseconds}ms-----------result:" + result);
listboxInfo.AppendText("\r\n");
}));
// 重置计时器以便下次使用
// stopwatch.Reset();
return;
var s2 = "";
// DetectImage_img(im_ptr, size.Width, size.Height, step, ref error[0]);
s2 = Encoding.UTF8.GetString(error);
bmp.UnlockBits(bmpData);
bmp.Dispose();
this.Invoke(new Action(() =>
{
//listboxInfo.
listboxInfo.AppendText(s2);
listboxInfo.AppendText("\r\n");
listboxInfo.AppendText("img_id=" + model.img_id);
listboxInfo.AppendText("\r\n");
foreach (var item in model.lables)
{
listboxInfo.AppendText("types=" + item.types);
listboxInfo.AppendText("\r\n");
listboxInfo.AppendText("scores=" + item.scores);
listboxInfo.AppendText("\r\n");
int i = 0;
string grid = string.Join(",", item.grid_corners);
int l = grid.Length;
listboxInfo.AppendText($"grid_corners=" + string.Join(",", item.grid_corners));
listboxInfo.AppendText("\r\n");
foreach (var item2 in item.grid_corners)
{
listboxInfo.AppendText($"grid_corners{i}=" + item2);
listboxInfo.AppendText("\r\n");
i++;
}
}
listboxInfo.AppendText("\r\n");
// listboxInfo.Items.Add(model.lables.grid_corners);
// listboxInfo.Items.Add(model.lables[0].types);
// listboxInfo.Items.Add(model.lables.scores);
}));
}
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
注意关闭程序时,将isProcessQueue=false,让线程自己关闭,不会出现异常。