2011-05-18 55 views
53

我知道如何使异步方法,但说我有一个方法,做了很多工作,然后返回一个布尔值?如何使一个异步方法返回一个值?

如何返回回调的布尔值?

澄清

public bool Foo(){ 
    Thread.Sleep(100000); // Do work 
    return true; 
} 

我希望能够让这个异步的。

回答

39

有这样做的几种方法......最简单的就是有异步方法也做了后续操作。另一种流行的方法是在一个回调来传递,即

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 
}); 
+0

回调方法的简单例子 – DRapp 2016-10-15 14:09:17

1

使用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; 
    } 
+0

后台工作这里是反生产力。你不知道AutoResetEvent/ManualResetEvent吗? – 2011-05-18 13:25:13

+1

@ the_drow我不同意这一点;一个BackgroundWorker和RunWorkerCompleted事件在这里是一个非常好的方法 – 2011-05-18 13:27:40

+0

@the_drow - 不,我不知道。我会看看我可以了解的。但如果你能解释为什么你认为这是反效果的,我想了解。 – NerdFury 2011-05-18 13:37:48

-1

你应该用你的异步方法的EndXXX返回值。 EndXXX应该等到使用IAsyncResult的WaitHandle有结果并返回值。

90

C# 5.0,你可以指定方法

public async Task<bool> doAsyncOperation() 
{ 
    // do work 
    return true; 
} 

bool result = await doAsyncOperation(); 
+19

对于任何关心的人来说,要使用'bool result = await doAsyncOperation();' – 2013-09-16 18:19:43

+1

每当你要使用“await”关键字时,它需要在方法,至少已标记为“异步”。我原本虽然只有工人的方法必须这样标记。例如,即使你的调用方法不会返回任何你必须命名为“异步无效MyCallerMethod” – 2014-10-27 16:52:53

+0

是的,但麻烦的警告,该方法将同步运行 – KingOfHypocrites 2015-06-18 17:25:51

3

也许这样做是为了创建一个委托,然后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); 
} 
+0

AsyncWaitHandle是一个WaitHandle。它没有WaitOne()方法。你必须把它放在任何等待完成的地方。 – 2011-05-18 20:54:06

+0

@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

+1

或者您可以将该代码粘贴到C#程序中并对其进行测试。它似乎为我工作。 – 2011-05-18 21:19:38

1

或许你可以尝试的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的继续该方法的价值..

相关问题