タスクとタイマーを実行する必要があります。タイマーが早く終了した場合は、別のタスクを実行し、最初と2番目のタスクの両方からの応答を待ち続け、最初に完了した結果を返します。そして、タイマーを再起動する必要があります。私はそのようなことをすると思います
foreach (var uri in Addresses)
{
var webRequest = CreateRequest(uri + "?query=" + query);
resultTasks.Add(ProcessRequestAsync(webRequest));
}
Task<string> firstFinishedTask = await Task.WhenAny(resultTasks);
<-- if timer end early -->
resultTasks.Add(<--newTask-->);
Task<string> firstFinishedTask = await Task.WhenAny(resultTasks);
しかし、リストにはすでに実行中のタスクがあるため、この時点でエラーが発生します。
あなたは何をお勧めできますか?
言い換えれば:私はタスクのリストを持っています
List<Task> tasksList = new List<Task>();
<-- some initialization of this list-->
次にTask.WhenAny(tasksList);
、WhenAnyに別のタスクを追加する方法を開始します。
私はあなたのための可能な解決策を見つけたと思います。しかし、Timer
私が使用する代わりにTask.Delay(...)
。
ここに含まれているサンプル・リサイズ・アプリケーションのコードでありButton btnStart
、ProgressBar progressBar
そしてRichTextBox log
その主なフォームには
CreateNextTask()
Task
必要に応じて新しいものを作成します。
GetWaitTask()
タイマーの役割を果たします。
それは機能しているようでした。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TaskAndTimer
{
public partial class MainForm : Form
{
private int[] taskConfigs = { 1200, 1300, 1100, 800 };
private Queue<int> queue;
public MainForm()
{
InitializeComponent();
}
private async void btnStart_Click(object sender, EventArgs e)
{
queue = new Queue<int>(taskConfigs);
Task<int> firstTask;
Task<int>[] tasks = new Task<int>[] { };
int result = -1;
progressBar.Style = ProgressBarStyle.Marquee;
do
{
log.AppendText($"Next round...{Environment.NewLine}");
log.AppendText($"-------------{Environment.NewLine}");
tasks =
tasks
.Concat(new[] { GetWaitTask(), CreateNextTask() })
.ToArray();
LogTasks("Current tasks:", tasks);
firstTask = await Task.WhenAny(tasks);
LogTasks("First task:", firstTask);
tasks = tasks.Except(new[] { firstTask }).ToArray();
LogTasks("Remaining tasks:", tasks);
result = await firstTask;
log.AppendText($"-------------{Environment.NewLine}");
log.AppendText(Environment.NewLine);
}
while (result == -1 && queue.Any());
log.AppendText($"result = [{result}]\r\n");
progressBar.Style = ProgressBarStyle.Blocks;
}
private Task<int> GetWaitTask()
{
return Task.Run(async () => { await Task.Delay(1000); return -1; });
}
private Task<int> CreateNextTask()
{
if (queue.Any())
{
int data = queue.Dequeue();
return Task.Run(async () => { await Task.Delay(data); return data; });
}
return Task.FromResult(-1);
}
private void LogTasks(string message, params Task<int>[] tasks)
{
log.AppendText(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fffffff"));
log.AppendText($"> {message}");
foreach (var task in tasks)
{
log.AppendText($" [{task.Id}];");
}
log.AppendText(Environment.NewLine);
}
}
}
そして結果はこれでした:
Next round...
-------------
2018-02-23 19:30:31.2273143> Current tasks: [2]; [4];
2018-02-23 19:30:32.2300773> First task: [2];
2018-02-23 19:30:32.2330774> Remaining tasks: [4];
-------------
Next round...
-------------
2018-02-23 19:30:32.2375774> Current tasks: [4]; [14]; [16];
2018-02-23 19:30:32.4392640> First task: [4];
2018-02-23 19:30:32.4452575> Remaining tasks: [14]; [16];
-------------
result = [1200]
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加