我有Web应用程序,它调用不同的Web服务来执行不同的工作。一些Web服务需要很长时间,有些很短。应用程序将并行调用所有Web服务以在完成或异常时获得结果。我已经开始编写代码,但我需要知道如何以最佳方式实现以下工作。
任何示例代码或网址都会对我有帮助。
protected async void btnAAC_Click(object sender, EventArgs e)
{
CancellationTokenSource cts = new CancellationTokenSource();
cts.CancelAfter(5000);
string[] retResult = null;
Task<string[]> taskResult = Run(cts.Token);
try
{
retResult = await taskResult;
//To do : display data
}
catch (OperationCanceledException ocex)
{
resultsTextBox.Text += "\r\nDownloads canceled.\r\n";
}
catch(Exception ex)
{
Debug.WriteLine(ex.ToString());
}
finally
{
cts.Dispose();
}
}
private async static Task<string[]> Run(CancellationToken cancellationToken)
{
HashSet<Task<string>> tasks = new HashSet<Task<string>>();
List<string> urlList = ServiceManager.SetUpURLList();
List<string> finalResult = new List<string>();
foreach (var work in urlList)
{
tasks.Add(Task.Run(() => DoWork(work, cancellationToken)));
}
try
{
while (tasks.Count > 0)
{
Task<string> finishedTask = await
Task.WhenAny(tasks.ToArray());
tasks.Remove(finishedTask);
finalResult.Add(finishedTask.Result);
}
return finalResult.ToArray();
}
finally
{
//CleanUpAfterWork();
}
}
public async static Task<string> DoWork(string url, CancellationToken cancellationToken)
{
while (true)
{
cancellationToken.ThrowIfCancellationRequested();
var html = await Downloader.DownloadHtml(url);
return html;
}
}
答案 0 :(得分:1)
如果任何网络服务需要超过5秒,任务将被取消,但剩余的任务将继续调用网络服务以获得结果或其他任务。
以下代码示例包含一种方法(and a Fiddle)。其RunTimeLimitedTask
方法包含策略的关键部分。
public static void Main()
{
DoIt().GetAwaiter().GetResult();
}
public async static Task DoIt()
{
var results = await Task.WhenAll(
RunTimeLimitedTask(10),
RunTimeLimitedTask(1000));
foreach(var result in results) Console.WriteLine(result);
}
public async static Task<string> RunTimeLimitedTask(int timeLimit)
{
// A
var source = new CancellationTokenSource();
source.CancelAfter(timeLimit);
// B
try {
await Task.Run(async () => await Task.Delay(500, source.Token));
// C
return "Complete";
}
catch (TaskCanceledException) {
// C
return "Cancelled";
}
}
答:为每个网络请求创建一个新的有时间限制的CancellationSource
。
B:在处理TaskCanceledException
的try catch块中包装等待的Web请求(我们模仿延迟的Task)。
C:通过返回传达成功/失败的字符串来处理成功和取消。要更好地制定策略,请返回具有更多结构的内容,例如Result<TSuccess, TFailure>
而不是返回string
。