Reputation: 58
I need to run Task and Timer, and if the timer ends earlier, then run another task and continue to wait for the answer from both the first and second tasks and return result of first completed. And I need to restart the timer. I think to do something like that
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);
But at this point I catch an error, because the list already has a running task.
What you can recomend?
In other words: I have list of tasks
List<Task> tasksList = new List<Task>();
<-- some initialization of this list-->
Then I start
Task.WhenAny(tasksList);
How I can add another Tasks to WhenAny?
Upvotes: 0
Views: 2567
Reputation: 103
If you must continue to wait for all tasks then try await Task.WhenAll(Task);
.
Also, it seems messy to order things in this way, possibly use a recursive function to send off each of your tasks and have your main thread in a while loop with a diagnostics timer on it. Then finally await all at the end after the loop.
readonly List<Task<T>> _taskList = new List<Task<T>>();
void fireThreads()
{
var timer = Stopwatch.StartNew();
var taskLoop = Task.Factory.StartNew(()=> DO STUFF);
_taskList.Add(taskLoop);
while(await Task.WhenAll(TaskList))
{
if (timer.ElapsedMilliseconds / 1000 > TargetTime)
fireThreads();
}
}
Definitely not the best code example but something like this might work.
Upvotes: 0
Reputation: 3246
I think I found a possible solution for you. But instead of Timer
I used Task.Delay(...)
.
Here is the code of the sample WinForms application which contains a Button btnStart
, a ProgressBar progressBar
and a RichTextBox log
on its main form.
CreateNextTask()
will create a new Task
if needed.
GetWaitTask()
plays the role of a timer.
It seemed working.
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);
}
}
}
And the result was this:
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]
Upvotes: 2