【问题标题】:How do you synchronously wait for the results of a event in C#?如何在 C# 中同步等待事件的结果?
【发布时间】:2019-04-22 03:01:16
【问题描述】:

在 C# 中的 Windows 应用程序中似乎有一种模式,您可以将“处理程序”分配给事件,并且该事件作为单独方法调用的副作用被触发。举个例子

ocrEngine = new OcrEngine();
ocrEngine.OcrResults += new OcrResultsEventHandler(ocrEngine_MethodThatProcessesTheResultsOfOcr); 

因此,例如,您有一个 OCR(光学字符识别)引擎,并且您想将图像传递给它,并返回一些文本。但是,在这个 API 中,我使用了传入图像的方法返回一个 int。即

int result = ocEngine.ReadImage(image);

这意味着我发现 OCR 过程是否使用 int 成功,即 0 = 成功。 但是实际结果在 'ocrEngine_MethodThatProcessesTheResultsOfOcr' 方法中返回。

如果我从控制台应用程序运行此程序,我试图了解我应该用来返回数据的模式,因为实际上没有明显的同步方式来返回实际结果。 事实上,每个对 ocEngine.ReadImage(image); 的方法调用显然至少有两个线程在运行。 我有一个涉及 Thread.Sleep 和检查布尔值的工作,但这似乎完全错误。

任何指导将不胜感激。

【问题讨论】:

  • 您是否有理由不能只访问将保存在变量中的值?喜欢ocrEngine.theResultOfRead()
  • 您可以在调用 ReadImage 后立即等待 AutoResetEvent,并在事件处理程序中设置 AutoResetEvent。虽然这不处理超时等错误。
  • 最直接的方法是使用ManulResetEventSlim这样的同步机制。主线程会调用Wait等待回调调用Set。或者,您可以使用 TaskCompletionSource 创建基于任务的异步 API。

标签: c# multithreading events delegates


【解决方案1】:

这里似乎没有完美的答案,除了使用以同步方式返回结果的 API 之外。 建议的最佳方法如下:

static AutoResetEvent autoResetEvent = new AutoResetEvent(false);
public static string Process(Bitmap image)
{
   ...
   int result = ocEngine.ReadImage(image);
   autoResetEvent.WaitOne(2500);
   ...
}

然后在回调事件中调用:

autoResetEvent.Set();

一旦工作完成。

但是,这种方法产生了更一致的结果,这可能是我们使用的 API 的结果,偶尔仍会导致超时/死锁问题。

【讨论】:

    猜你喜欢
    • 2020-10-20
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 2012-06-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多