Sử dụng Nhiệm vụ cho thời gian chờ tùy chỉnh trên phương pháp async
đây thực hiện của tôi về một lớp tùy chỉnh với một phương pháp để quấn một nhiệm vụ để có một thời gian chờ .
public class TaskWithTimeoutWrapper
{
protected volatile bool taskFinished = false;
public async Task<T> RunWithCustomTimeoutAsync<T>(int millisecondsToTimeout, Func<Task<T>> taskFunc, CancellationTokenSource cancellationTokenSource = null)
{
this.taskFinished = false;
var results = await Task.WhenAll<T>(new List<Task<T>>
{
this.RunTaskFuncWrappedAsync<T>(taskFunc),
this.DelayToTimeoutAsync<T>(millisecondsToTimeout, cancellationTokenSource)
});
return results[0];
}
public async Task RunWithCustomTimeoutAsync(int millisecondsToTimeout, Func<Task> taskFunc, CancellationTokenSource cancellationTokenSource = null)
{
this.taskFinished = false;
await Task.WhenAll(new List<Task>
{
this.RunTaskFuncWrappedAsync(taskFunc),
this.DelayToTimeoutAsync(millisecondsToTimeout, cancellationTokenSource)
});
}
protected async Task DelayToTimeoutAsync(int millisecondsToTimeout, CancellationTokenSource cancellationTokenSource)
{
await Task.Delay(millisecondsToTimeout);
this.ActionOnTimeout(cancellationTokenSource);
}
protected async Task<T> DelayToTimeoutAsync<T>(int millisecondsToTimeout, CancellationTokenSource cancellationTokenSource)
{
await this.DelayToTimeoutAsync(millisecondsToTimeout, cancellationTokenSource);
return default(T);
}
protected virtual void ActionOnTimeout(CancellationTokenSource cancellationTokenSource)
{
if (!this.taskFinished)
{
cancellationTokenSource?.Cancel();
throw new NoInternetException();
}
}
protected async Task RunTaskFuncWrappedAsync(Func<Task> taskFunc)
{
await taskFunc.Invoke();
this.taskFinished = true;
}
protected async Task<T> RunTaskFuncWrappedAsync<T>(Func<Task<T>> taskFunc)
{
var result = await taskFunc.Invoke();
this.taskFinished = true;
return result;
}
}
Sau đó, bạn có thể gọi nó như thế này:
await new TaskWithTimeoutWrapper().RunWithCustomTimeoutAsync(10000,() => this.MyTask());
hoặc
var myResult = await new TaskWithTimeoutWrapper().RunWithCustomTimeoutAsync(10000,() => this.MyTaskThatReturnsMyResult());
Và bạn có thể thêm một mã thông báo hủy bỏ nếu bạn muốn hủy bỏ nhiệm vụ async chạy nếu nó được để hết giờ.
Hy vọng nó giúp
Bạn sẽ muốn nhìn vào [Stopwatch] (http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx) lớp. [Ở đây] (http://stackoverflow.com/a/5019172/95573) là một ví dụ – SwDevMan81
Loại 'tryMethod' làm gì? Trong đoạn mã trên, câu lệnh if của bạn sẽ chỉ đạt được sau khi 'trymethod' đã hoàn tất. – JMK
Điều này có vẻ giống như một cái gì đó bạn có thể muốn thực thi không đồng bộ? – emd