我知道如何制作异步方法,但是说我有一个方法需要大量工作,然后返回布尔值?
如何在回调中返回布尔值?
澄清:
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
我希望能够使此异步。
Answers:
有几种方法可以做...最简单的是让async方法也执行后续操作。另一种流行的方法是传递回调,即
void RunFooAsync(..., Action<bool> callback) {
// do some stuff
bool result = ...
if(callback != null) callback(result);
}
另一种方法是在异步操作完成后引发一个事件(结果存储在event-args数据中)。
另外,如果您使用的是TPL,则可以使用ContinueWith
:
Task<bool> outerTask = ...;
outerTask.ContinueWith(task =>
{
bool result = task.Result;
// do something with that
});
在C#5.0中,您可以将方法指定为
public async Task<bool> doAsyncOperation()
{
// do work
return true;
}
bool result = await doAsyncOperation();
bool result = await doAsyncOperation();
return await Task.FromResult(true)
将取消该警告。
await
在方法主体中进行操作,否则这实际上不会异步执行任何操作。返回Task.FromResult(true)
并没有改变。方法主体在调用者的线程上同步运行,直到第一次等待。
可能最简单的方法是创建一个委托,然后创建BeginInvoke
,然后在将来的某个时间等待,然后创建一个EndInvoke
。
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
public SomeMethod()
{
var fooCaller = new Func<bool>(Foo);
// Call the method asynchronously
var asyncResult = fooCaller.BeginInvoke(null, null);
// Potentially do other work while the asynchronous method is executing.
// Finally, wait for result
asyncResult.AsyncWaitHandle.WaitOne();
bool fooResult = fooCaller.EndInvoke(asyncResult);
Console.WriteLine("Foo returned {0}", fooResult);
}
WaitHandle.WaitOne
方法的文档:msdn.microsoft.com/en-us/library/58195swd.aspx
使用BackgroundWorker。它将允许您在完成时获取回调并跟踪进度。您可以将事件参数上的Result值设置为结果值。
public void UseBackgroundWorker()
{
var worker = new BackgroundWorker();
worker.DoWork += DoWork;
worker.RunWorkerCompleted += WorkDone;
worker.RunWorkerAsync("input");
}
public void DoWork(object sender, DoWorkEventArgs e)
{
e.Result = e.Argument.Equals("input");
Thread.Sleep(1000);
}
public void WorkDone(object sender, RunWorkerCompletedEventArgs e)
{
var result = (bool) e.Result;
}
也许您可以尝试像这样开始BeginInvoke指向您的方法的委托:
delegate string SynchOperation(string value);
class Program
{
static void Main(string[] args)
{
BeginTheSynchronousOperation(CallbackOperation, "my value");
Console.ReadLine();
}
static void BeginTheSynchronousOperation(AsyncCallback callback, string value)
{
SynchOperation op = new SynchOperation(SynchronousOperation);
op.BeginInvoke(value, callback, op);
}
static string SynchronousOperation(string value)
{
Thread.Sleep(10000);
return value;
}
static void CallbackOperation(IAsyncResult result)
{
// get your delegate
var ar = result.AsyncState as SynchOperation;
// end invoke and get value
var returned = ar.EndInvoke(result);
Console.WriteLine(returned);
}
}
然后,使用您以AsyncCallback发送的方法中的值继续。