patterncsharpMinor
Long running, frequent async advice?
Viewed 0 times
asynclongadvicerunningfrequent
Problem
A user must query a large database for information repeatedly. This query may take up to ~7 seconds. This must be done asynchronously. Only one query will be running at a time.
I did not create a new thread for each query as the code would be less clean, less maintable, etc.
I did not use ThreadPool.QueueUserWorkItem as this will tie up a ThreadPool thread. I'd rather not increase the minimum ThreadPool threads for this via ThreadPool.SetMinThreads as this won't be used by every user.
Considering the above, and that this problem seems to come up in this project often, I decided to create my own single thread "ThreadPool" which just processes items. No new threads created, no ThreadPool thread occupied, reusable elsewhere...
Should I have avoided the built-in .net ThreadPool? Is there a better approach I've missed?
I've included source for clarity. I'm not looking for code critique as much as I am advice on what to do in this scenario. I do not have access to
SingleThreadPool
```
public class SingleThreadPool : IThreadPool
{
private readonly Thread thread;
private readonly Queue queue;
private readonly AutoResetEvent resetEvent;
public SingleThreadPool()
{
this.queue = new Queue();
this.resetEvent = new AutoResetEvent(false);
this.IsDisposed = false;
this.thread = new Thread(Run);
this.thread.IsBackground = true;
this.thread.Name = "SingleThreadPool";
this.thread.Start();
}
~SingleThreadPool()
{
this.Dispose(true);
}
public void Dispose()
{
this.Dispose(false);
//keeps destructor from executing.
GC.SuppressFinalize(this);
}
private void Dispose(bool calledFromFinalizer)
{
if (!this.IsDisposed)
{
CallbackTask[] cpy = null;
lock (this.queue)
{
cpy = this.queue.ToArray();
queue.C
I did not create a new thread for each query as the code would be less clean, less maintable, etc.
I did not use ThreadPool.QueueUserWorkItem as this will tie up a ThreadPool thread. I'd rather not increase the minimum ThreadPool threads for this via ThreadPool.SetMinThreads as this won't be used by every user.
Considering the above, and that this problem seems to come up in this project often, I decided to create my own single thread "ThreadPool" which just processes items. No new threads created, no ThreadPool thread occupied, reusable elsewhere...
Should I have avoided the built-in .net ThreadPool? Is there a better approach I've missed?
I've included source for clarity. I'm not looking for code critique as much as I am advice on what to do in this scenario. I do not have access to
async/await, for those who want to critique source.SingleThreadPool
```
public class SingleThreadPool : IThreadPool
{
private readonly Thread thread;
private readonly Queue queue;
private readonly AutoResetEvent resetEvent;
public SingleThreadPool()
{
this.queue = new Queue();
this.resetEvent = new AutoResetEvent(false);
this.IsDisposed = false;
this.thread = new Thread(Run);
this.thread.IsBackground = true;
this.thread.Name = "SingleThreadPool";
this.thread.Start();
}
~SingleThreadPool()
{
this.Dispose(true);
}
public void Dispose()
{
this.Dispose(false);
//keeps destructor from executing.
GC.SuppressFinalize(this);
}
private void Dispose(bool calledFromFinalizer)
{
if (!this.IsDisposed)
{
CallbackTask[] cpy = null;
lock (this.queue)
{
cpy = this.queue.ToArray();
queue.C
Solution
If you are using .Net 4.0 you can use
Tasks:// Create a scheduler that uses two threads.
LimitedConcurrencyLevelTaskScheduler lcts =
new LimitedConcurrencyLevelTaskScheduler(1);
List tasks = new List();
// Create a TaskFactory and pass it our custom scheduler.
TaskFactory factory = new TaskFactory(lcts);
//...
public void InitiateNewTask() {
Task t = factory.StartNew(() => {
// your code here
}, cts.Token);
tasks.Add(t);
}Code Snippets
// Create a scheduler that uses two threads.
LimitedConcurrencyLevelTaskScheduler lcts =
new LimitedConcurrencyLevelTaskScheduler(1);
List<Task> tasks = new List<Task>();
// Create a TaskFactory and pass it our custom scheduler.
TaskFactory factory = new TaskFactory(lcts);
//...
public void InitiateNewTask() {
Task t = factory.StartNew(() => {
// your code here
}, cts.Token);
tasks.Add(t);
}Context
StackExchange Code Review Q#41612, answer score: 2
Revisions (0)
No revisions yet.