我知道如何使異步方法,但說我有一個方法,做了很多工作,然後返回一個布爾值?如何使一個異步方法返回一個值?
如何返回回調的布爾值?
澄清:
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