使用同步方法包装异步调用

时间:2012-07-31 05:03:45

标签: c# asynchronous

我有一个带有异步方法的第三方DLL,我想用另一个等待其结果的方法包装。

我开始编写一个类来隐藏功能,但现在我无法理解如何在Doc.Completed this.version.DownloadFile(this)之后等待Doc.Download {}} {}后调用InitTransfer

DLL多次调用OnProgressNotify,然后调用Completed,然后调用OnErrorCompleted可以在任何阶段调用,但InitTransfer总是最后调用。我不关心OnProgressNotifyOnErrorpublic class Doc : SomeInterfaceFromTheDll { private readonly IVersion version; // An interface from the DLL. private bool downloadSuccessful; public Doc(IVersion version) { this.version = version; } public bool Download() { this.version.DownloadFile(this); return ??? // I want to return this.downloadSuccessful after Completed() runs. } public void Completed(short reason) { Trace.WriteLine(string.Format("Notify.Completed({0})", reason)); this.downloadSuccessful = reason == 0 ? true : false; } public void InitTransfer(int totalSize) { Trace.WriteLine(string.Format("Notify.InitTransfer({0})", totalSize)); } public void OnError(string errorText) { Trace.WriteLine(string.Format("Notify.OnError({0})", errorText)); } public void OnProgressNotify(int bytesRead) { Trace.WriteLine(string.Format("Notify.OnProgressNotify({0})", bytesRead)); } }

我读过 Asynchronous call in synchronous methodTurn asynchronous calls into synchronous但我不明白如何应用此案例的答案。

我正在使用C#4。

{{1}}

1 个答案:

答案 0 :(得分:1)

这可以使用ManualResetEvent实现,如下所示。但有几点需要注意。主要的一点是,此机制不允许您同时在多个线程上的相同的 Download()实例上调用Doc。如果您需要这样做,则可能需要采用不同的方法。

public class Doc : SomeInterfaceFromTheDll
{
  private readonly IVersion version; // An interface from the DLL.
  private readonly ManualResetEvent _complete = new ManualResetEvent(false);

  private bool downloadSuccessful;

  // ...

  public bool Download()
  {
    this.version.DownloadFile(this);
    // Wait for the event to be signalled...
    _complete.WaitOne();
    return this.downloadSuccessful;
  }

  public void Completed(short reason)
  {
    Trace.WriteLine(string.Format("Notify.Completed({0})", reason));
    this.downloadSuccessful = reason == 0;
    // Signal that the download is complete
    _complete.Set();
  }

  // ...
}