塞維是對的。因爲它已經使用另一個線程異步,或者任務可能不是必需的。但你可以使用這個TaskCompletionSource。
public void MethodOne()
{
MethodTwo()
.ContinueWith(task =>
{
if (task.IsFaulted)
// Handle error in task.Exception
;
else
{
object obj = task.Result;
// Handle object
}
});
}
public Task<object> MethodTwo()
{
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>();
//Conduct async call to external server
AppServer.MakeCall(response =>
{
if (Response.IsValid)
tcs.TrySetResult(response.Object);
else
tcs.TrySetException(new FooException());
});
return tcs.Task;
}
你也可以做的try/catch的MethodTwo拉姆達參數內部和/或使用完整的Response對象,而不是響應數據的對象實例only.`
public void MethodOne()
{
MethodTwo(response =>
{
if (Response.IsValid)
callback(Response.Object);
else
throw new FooException(); // Or error handling directly
});
}
public void MethodTwo(Action<Response> callback)
{
//Conduct async call to external server
AppServer.MakeCall(response =>
{
callback(response);
});
}
如果不允許有從MethodOne一個Response對象的引用,和/或不允許更改回調簽名,然後你可以調用使用FooException回調動作作爲參數callback(new FooException);
public void MethodOne()
{
MethodTwo(response =>
{
if (response is FooException)
{
FooException exc = response as FooException;
}
else
{
// Handle response;
}
});
}
public void MethodTwo(Action<object> callback)
{
//Conduct async call to external server
AppServer.MakeCall(response =>
{
if (Response.IsValid)
callback(Response.Object);
else
callback(new FooException());
});
}
爲了繁榮,我選擇了傳遞兩個回調。一個成功,一個失敗。我使他們都是匿名的,所以它的工作非常整潔。 –