我知道如何使异步方法,但说我有一个方法,做了很多工作,然后返回一个布尔值?如何使一个异步方法返回一个值?
如何返回回调的布尔值?
澄清:
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
我希望能够让这个异步的。
我知道如何使异步方法,但说我有一个方法,做了很多工作,然后返回一个布尔值?如何使一个异步方法返回一个值?
如何返回回调的布尔值?
澄清:
public bool Foo(){
Thread.Sleep(100000); // Do work
return true;
}
我希望能够让这个异步的。
有这样做的几种方法......最简单的就是有异步方法也做了后续操作。另一种流行的方法是在一个回调来传递,即
void RunFooAsync(..., Action<bool> callback) {
// do some stuff
bool result = ...
if(callback != null) callback(result);
}
另一种方法是提高一个事件(其结果在事件ARGS数据)时,异步操作完成。
此外,如果您使用的是第三方物流,可以使用ContinueWith
:
Task<bool> outerTask = ...;
outerTask.ContinueWith(task =>
{
bool result = task.Result;
// do something with that
});
使用BackgroundWorker。它可以让你完成回调,并让你跟踪进度。您可以将事件参数的结果值设置为结果值。
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;
}
后台工作这里是反生产力。你不知道AutoResetEvent/ManualResetEvent吗? – 2011-05-18 13:25:13
@ the_drow我不同意这一点;一个BackgroundWorker和RunWorkerCompleted事件在这里是一个非常好的方法 – 2011-05-18 13:27:40
@the_drow - 不,我不知道。我会看看我可以了解的。但如果你能解释为什么你认为这是反效果的,我想了解。 – NerdFury 2011-05-18 13:37:48
你应该用你的异步方法的EndXXX返回值。 EndXXX应该等到使用IAsyncResult的WaitHandle有结果并返回值。
从C# 5.0,你可以指定方法
public async Task<bool> doAsyncOperation()
{
// do work
return true;
}
bool result = await doAsyncOperation();
对于任何关心的人来说,要使用'bool result = await doAsyncOperation();' – 2013-09-16 18:19:43
每当你要使用“await”关键字时,它需要在方法,至少已标记为“异步”。我原本虽然只有工人的方法必须这样标记。例如,即使你的调用方法不会返回任何你必须命名为“异步无效MyCallerMethod” – 2014-10-27 16:52:53
是的,但麻烦的警告,该方法将同步运行 – KingOfHypocrites 2015-06-18 17:25:51
也许这样做是为了创建一个委托,然后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);
}
AsyncWaitHandle是一个WaitHandle。它没有WaitOne()方法。你必须把它放在任何等待完成的地方。 – 2011-05-18 20:54:06
@the_drow:你可能想看看这个例子:http://msdn.microsoft.com/en-us/library/system.iasyncresult.asyncwaithandle.aspx。另请参阅'WaitHandle.WaitOne'方法的文档:http://msdn.microsoft.com/en-us/library/58195swd.aspx – 2011-05-18 21:08:39
或者您可以将该代码粘贴到C#程序中并对其进行测试。它似乎为我工作。 – 2011-05-18 21:19:38
或许你可以尝试的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的继续该方法的价值..
回调方法的简单例子 – DRapp 2016-10-15 14:09:17