Shemesh
Shemesh
CC#
Created by Shemesh on 8/11/2024 in #help
Running synchronous tasks on separate thread with FIFO
Hey guys, I want to handle synchronous tasks that will run on another thread while the main thread is running. The separate tasks will write logs but is should be by order - FIFO. I wrote the following class but I'm not sure how can I send the tasks as synchronous ones:
c#
using System;
...

namespace mynamespace
{
public class TaskQueue
{
private readonly ConcurrentQueue<Func<Task>> _tasks = new ConcurrentQueue<Func<Task>>();
private readonly SemaphoreSlim _signal = new SemaphoreSlim(1);

public void Enqueue(Func<Task> task)
{
_tasks.Enqueue(task);
Task.Run(ProcessQueue);
}

public async Task EnqueueAsync(Func<Task> task)
{
_tasks.Enqueue(task);
await ProcessQueue();
}

private async Task ProcessQueue()
{
await _signal.WaitAsync();
try
{
if (_tasks.TryDequeue(out var task))
{
await task();
}
}
finally
{
_signal.Release();
}
}

public int GetQueueCount()
{
return _tasks.Count;
}

public IEnumerable<Func<Task>> GetTasksInQueue()
{
return _tasks.ToArray();
}

public async Task WaitUntilEmpty()
{
int timeout = 300;//30 seconds
while (_tasks.Count > 0 && timeout >= 0)
{
await Task.Delay(100);
timeout--;
}
if(timeout == 0)
{
Debug.WriteLine("TaskQueue did not empty in 30 seconds");
}
}
}
}
c#
using System;
...

namespace mynamespace
{
public class TaskQueue
{
private readonly ConcurrentQueue<Func<Task>> _tasks = new ConcurrentQueue<Func<Task>>();
private readonly SemaphoreSlim _signal = new SemaphoreSlim(1);

public void Enqueue(Func<Task> task)
{
_tasks.Enqueue(task);
Task.Run(ProcessQueue);
}

public async Task EnqueueAsync(Func<Task> task)
{
_tasks.Enqueue(task);
await ProcessQueue();
}

private async Task ProcessQueue()
{
await _signal.WaitAsync();
try
{
if (_tasks.TryDequeue(out var task))
{
await task();
}
}
finally
{
_signal.Release();
}
}

public int GetQueueCount()
{
return _tasks.Count;
}

public IEnumerable<Func<Task>> GetTasksInQueue()
{
return _tasks.ToArray();
}

public async Task WaitUntilEmpty()
{
int timeout = 300;//30 seconds
while (_tasks.Count > 0 && timeout >= 0)
{
await Task.Delay(100);
timeout--;
}
if(timeout == 0)
{
Debug.WriteLine("TaskQueue did not empty in 30 seconds");
}
}
}
}
any suggestions how can I send to Enqueue method a synchronous task? thanks!
23 replies