我有一個異步操作取決於另一臺服務器,它需要大部分隨機的時間來完成。在異步操作正在運行的同時,「主線程」中還有一些處理正在進行,這也需要花費一定的時間來完成。異步延遲超時任務
主線程啓動異步任務,執行它的主要任務,並在最後檢查異步任務的結果。
異步線程拉取數據並計算對主線程完成不重要的字段。然而,如果計算能夠完成而沒有減慢的主線程,則該數據將會很好(並且應該被包括)。
我想設置異步任務,在最小運行2秒,但 採取一切開始和主要任務結束之間的可用時間。 這是一個'延遲超時',因爲如果超過第二個運行時間並且實際上正在請求結果,則它僅超時。 (異步 任務應採取更大的2秒,或 主要任務的總運行時間)
EDIT(試圖澄清的要求):如果異步任務有機會運行持續2秒鐘,它根本不應該阻塞主線程。主線程必須允許異步任務至少運行2秒。此外,如果主線程需要超過2秒才能完成,則應允許異步任務與主線程一樣運行。
我設計了一個可以工作的包裝,但是我更喜歡一個實際上是Task類型的解決方案。看到我下面的包裝解決方案。
public class LazyTimeoutTaskWrapper<tResult>
{
private int _timeout;
private DateTime _startTime;
private Task<tResult> _task;
private IEnumerable<Action> _timeoutActions;
public LazyTimeoutTaskWrapper(Task<tResult> theTask, int timeoutInMillis, System.DateTime whenStarted, IEnumerable<Action> onTimeouts)
{
this._task = theTask;
this._timeout = timeoutInMillis;
this._startTime = whenStarted;
this._timeoutActions = onTimeouts;
}
private void onTimeout()
{
foreach (var timeoutAction in _timeoutActions)
{
timeoutAction();
}
}
public tResult Result
{
get
{
var dif = this._timeout - (int)System.DateTime.Now.Subtract(this._startTime).TotalMilliseconds;
if (_task.IsCompleted ||
(dif > 0 && _task.Wait(dif)))
{
return _task.Result;
}
else
{
onTimeout();
throw new TimeoutException("Timeout Waiting For Task To Complete");
}
}
}
public LazyTimeoutTaskWrapper<tNewResult> ContinueWith<tNewResult>(Func<Task<tResult>, tNewResult> continuation, params Action[] onTimeouts)
{
var result = new LazyTimeoutTaskWrapper<tNewResult>(this._task.ContinueWith(continuation), this._timeout, this._startTime, this._timeoutActions.Concat(onTimeouts));
result._startTime = this._startTime;
return result;
}
}
有沒有人比這個包裝有更好的解決方案?
我很好奇你爲什麼想要後臺任務花費比完成實際工作所需的時間更長的時間。 – 2012-02-04 17:12:19
這不應該花費比實際工作時間更長的時間。主線程只需要等待至多2秒,但如果主線程太忙而不能立即需要結果,則主線程要允許它運行超過2秒。如果主線程花費了2秒多的時間完成,主線程根本不想等待。 – hannasm 2012-02-04 17:28:54