我已经在我正在尝试做的事情之下放置了一些非常基本的代码。我有'DoSomethingAshnc'方法执行异步操作。我希望'DoSomething'方法是一个不接受action参数并返回int的同步方法。
public void DoSomething(Action<int> actionToPerformOnComplete)
{
DoSomethingAsync(delegate(int val)
{
actionToPerformOnComplete(val);
});
}
甚至可以让'DoSomething'返回一个整数,就像方法同步发生一样?
答案 0 :(得分:6)
您需要在同步方法的最后添加一些内容,告诉它等待另一个调用完成。我假设您的异步方法将有一个事件告诉调用者何时完成。
如果是这样,那么我建议使用像ManualResetEvent这样的东西,在同步线程中等待它,并在异步事件的Finish事件接收器中设置它。
示例:
public void DoSomething(Action<int> actionToPerformOnComplete)
{
ManualResetEvent mre = new ManualResetEvent(false);
DoSomethingAsync(delegate(int val)
{
try
{
actionToPerformOnComplete(val);
}
finally
{
mre.Set();
}
});
mre.WaitOne();
}
答案 1 :(得分:1)
是。你所要做的就是把这行代码放在一边:
IAsyncResult asycn = ... // make a call to Async and get back IAsyncResult
while(!asycn.IsCompleted)
{
Thread.Sleep( ....);
}
正如有人问的那样,正确设计的异步操作将实现async pattern MSDN:
使用的异步操作 IAsyncResult设计模式是 实现为两个名为的方法 BeginOperationName和 EndOperationName开始和结束 异步操作 OperationName分别为。对于 例如,FileStream类提供 BeginRead和EndRead方法 从文件中异步读取字节。 这些方法实现了 Read的异步版本 方法
答案 2 :(得分:1)
正如其他人所提到的,您需要等待异步方法完成。要在不将Action
参数传递给方法的情况下执行此操作,请使用以下代码:
public int DoSomething()
{
int result;
ManualResetEvent mre = new ManualResetEvent(false);
DoSomethingAsync(val => {result = val; mre.Set(); });
mre.WaitOne();
return result;
}
执行异步方法,等待它完成并将结果分配给局部变量。返回此结果。
答案 3 :(得分:0)
using System;
using System.Threading;
namespace qqq
{
class Program
{
public static void DoAsync(Action<int> whenDone)
{
new Thread(o => { Thread.Sleep(3000); whenDone(42); }).Start();
}
static public int Do()
{
var mre = new ManualResetEvent(false);
int retval = 0;
DoAsync(i => { retval = i; mre.Set(); });
if (mre.WaitOne())
return retval;
throw new ApplicationException("Unexpected error");
}
static void Main(string[] args)
{
Console.WriteLine(Do());
}
}
}