使用C#进行OCR的多线程实现

3

我需要在WinForms C#应用程序中实现多线程,以下是需要OCR不同类型数据的独立方法。我们有一张图像,其中包含文本数字

decimal[] numbers = getNumbers(bitmap, dictionary1);
string[] text = getText(bitmap, dictionary2);
int[] integers = getInts(bitmap, dictionary3);
// add 5 more data types (list, int[], etc..)

因此,整个过程大约需要1秒钟。

我在考虑同时在不同的线程上运行OCR。为此,我尝试使用Task Factory:

decimal[] numbers;
Task.Factory.StartNew(() =>
{numbers = getNumbers(bitmap, dictionary1);});
string[] text;
Task.Factory.StartNew(() =>
{text = getText(bitmap, dictionary2);});
textBox1.Text = "" + text[0]; // nothing

我是一名有用的助手,能够翻译文本。

但我没有得到任何结果。

那么,在我的情况下是否可以实现多线程?我应该使用哪种方法?

  • 任务工厂
  • 后台工作者
  • 线程
  • 还是其他什么东西?

如果可能的话,您能否就如何使用您的方法给我一些建议,因为当我尝试使用TaskFactory时失败了(如示例所示)。

编辑:

似乎

textBox1.Text = "" + text[0];

执行速度比

更快。
string[] text;
Task.Factory.StartNew(() =>
{text = getText(bitmap, dictionary2);});

这就是为什么TextBox字段为空..所以我把"textBox1.Text = "" + text[0];"移到了代码的最后,最终获得了结果。
编辑2:好的,任务没有任何区别..我得到了相同的速度测试结果,没有它们。

你的实际代码是否等待任务完成? - erikH
1个回答

4

您已经正确地启动了任务,但却从未等待其完成。您需要做的类似于以下内容;

Task[] tasks = new Task[2];
decimal[] numbers;
tasks[0] = Task.Factory.StartNew(() =>
   {numbers = getNumbers(bitmap, dictionary1);});
string[] text;
tasks[1] = Task.Factory.StartNew(() =>
   {text = getText(bitmap, dictionary2);});

Task.WaitAll(tasks);  // Wait for all parallel tasks to finish 
                      // before using their output.

textBox1.Text = "" + text[0];

可以在这里找到更多的示例代码。

或者,您可以直接从任务中返回值而不是将其分配给变量,并使用Task.Result。当您访问它时,它会等待任务完成并返回任务的结果。


任务并没有产生任何影响。即使没有它们,我得到的速度测试结果也是一样的。 - Alex
@Alex 很难在没有看到新代码的情况下解释清楚,但是你是否先启动所有任务并在它们全部运行后再访问结果?如果你在开始下一个任务之前单独等待每个任务的结果,那么你会得到相同的效果。 - Joachim Isaksson
我按你的例子开始运行它们:run1,run2,run3 ->>> WaitAll。然后我将收集到的信息放入textBoxes中。而且这还不是全部。在第一次运行时没有任何错误,但是当我第二次运行代码时,会出现“对象引用未设置为对象的实例”的错误(除非将麻烦的那一行放入一个单独的task[])。 - Alex
抱歉,是我犯了错。最终,我知道了导致我所说的错误的原因。性能提高了200+毫秒,这结果并不算太差。一切都比1秒好;) - Alex

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接