gpt4 book ai didi

c# - 是否有一种通用的方法来同步异步方法?

转载 作者:可可西里 更新时间:2023-11-01 08:47:01 24 4
gpt4 key购买 nike

我们有一个常见的场景,我们有一个方法异步执行一些操作并在完成时引发一个事件。

有时我们希望它同步完成,所以我们的代码看起来类似于:

ManualResetEvent reset = new ManualResetEvent(false);
someobject.AsyncActionDone += (sender, args) => reset.Set();
someobject.PerformAsyncAction();
reset.WaitOne();

有没有办法编写一个辅助方法来做到这一点?我可以传递要执行的操作,但我不确定如何传递让辅助方法知道要监听哪个事件的东西,因为它看起来不像你可以传递 EventHandler 作为参数。

最好是不需要反射的方案

似乎有些困惑,这是某个对象的类的示例:

public class SomeClass
{
private ExternalServer someServerOverTheNetwork = new ExternalServer();

public event EventHandler AsyncActionDone;
public Data SomeData { get; set; }
public void PerformAsyncAction()
{
someServerOverTheNetwork.GetSomeData(OnDataRetrived);
}

public Data OnDataRetrived(Data someData)
{
AsyncActionDone(this, new DataEventArgs(someData));
}
}

最佳答案

我会考虑实现 Asynchronous Design Pattern在执行异步操作的对象中。

public object Operation(object arg)
{
var ar = BeginOperation(arg, null, null);

return EndOperation(ar);
}

public IAsyncResult BeginOperation(object arg, AsyncCallback asyncCallback, object state)
{
AsyncResult asyncResult = new AsyncResult(asyncCallback, state);

// Lauch the asynchronous operation

return asyncResult;
}

private void LaunchOperation(AsyncResult asyncResult)
{
// Do something asynchronously and call OnOperationFinished when finished
}

private void OnOperationFinished(AsyncResult asyncResult, object result)
{
asyncResult.Complete(result);
}


public object EndOperation(IAsyncResult asyncResult)
{
AsyncResult ar = (AsyncResult)asyncResult;

return ar.EndInvoke();
}

使用此模式,您可以灵活地对对象进行多个并发异步操作。

注意:您可以在网络上轻松找到通用 AsyncResult 类的实现。

编辑:

因为你想保持当前的设计,如果你的所有对象只能有一个异步操作,那么你可以定义一个 IAsyncOperation 接口(interface)并在你的所有对象中实现它。

public interface IAsyncOperation
{
event EventHandler AsyncActionDone;
void PerformAsyncAction();
}

那么你可以:

public static CallSynchronously(IAsyncOperation asyncOperation)
{
ManualResetEvent reset = new ManualResetEvent(false);
asyncOperation.AsyncActionDone += (sender, args) => reset.Set();
asyncOperation.PerformAsyncAction();
reset.WaitOne();
}

如果你的对象可以包含多个异步操作,那么没有反射我认为没有办法实现你想做的事情,但你仍然可以定义一个包含 ManualResetEvent 的所有异步操作的同步版本。

public void PerformAction()
{
ManualResetEvent reset = new ManualResetEvent(false);
this.AsyncActionDone += (sender, args) => reset.Set();
this.PerformAsyncAction();
reset.WaitOne();
}

关于c# - 是否有一种通用的方法来同步异步方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2255680/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com