我有一个带有异步方法的第三方DLL,我想用另一个等待其结果的方法包装。
我开始编写一个类来隐藏功能,但现在我无法理解如何在Doc.Completed
this.version.DownloadFile(this)
之后等待Doc.Download
{}} {}后调用InitTransfer
。
DLL多次调用OnProgressNotify
,然后调用Completed
,然后调用OnError
。 Completed
可以在任何阶段调用,但InitTransfer
总是最后调用。我不关心OnProgressNotify
,OnError
或public 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 method和Turn asynchronous calls into synchronous但我不明白如何应用此案例的答案。
我正在使用C#4。
{{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();
}
// ...
}