newprint
newprint

Reputation: 7136

Efficient way to schedule multiple threads from ThreadPool to be exetuted in the future?

I want to use threads from ThreadPool to run same procedure at different time. Here is what I am trying to accomplish:

  1. add an item to the hash,
  2. note the time when item was created, and within X0 minutes
  3. go back and remove/do something from/with item from the hash.

From what I have read, using .Sleep() to delay execution is terrible idea. What would be better idea ?

(Unfortunately, I can't use Task Parallel Library, and limited only to .NET 3.5)

Upvotes: 0

Views: 195

Answers (2)

Peter Duniho
Peter Duniho

Reputation: 70691

I don't know how TPL would be useful here anyway. I don't recall anything in it that involves scheduling things for future execution.

.NET includes two different basic Timer classes (in System.Timers and System.Threading), and a third one specifically for Forms (in case you're doing that). Those are the "go-to" API for this specific application.

One alternative you might consider is creating a single thread that consumes a queue of scheduled tasks, essentially implementing your own timer. In that one thread, you'd wind up using Thread.Sleep(). Yes, normally one would want to avoid that, but in a dedicated thread specifically for the purpose, it's fine. Whether you'd find that more desirable than the use of one of the Timer classes, I don't know, since I don't really understand the resistance to using one of the Timer classes.

Note that the System.Threading.Timer class has a "one-shot" mode. By passing Timeout.Infinite as the repeat interval, the timer callback is executed only once, after the initial due time interval has elapsed. The only "management" necessary is to retain a reference to the Timer instance to ensure it's not garbage-collected before the timer period elapses.

It even uses ThreadPool threads.

Upvotes: 1

Enigmativity
Enigmativity

Reputation: 117104

Here's an approach using Microsoft's Reactive Framework (NuGet Rx-Main):

var query =
    Observable.Create<HashAction>(o =>
    {
        var hash = "Create Hash Somehow";
        return Observable
            .Return(new HashAction()
            {
                Action = "Add",
                Hash = hash
            })
            .Concat(
                Observable
                    .Timer(TimeSpan.FromMinutes(1.0))
                    .Select(x => new HashAction()
                    {
                        Action = "Remove",
                        Hash = hash
                    }))
            .Subscribe(o);
    });

query.Subscribe(x =>
{
    if (x.Action == "Add")
    {
        /* Add Hash */
    }
    if (x.Action == "Remove")
    {
        /* Remove Hash */
    }
});

Now, it's a bit contrived as you don't give very much concrete detail as to what you're trying to do. I don't understand what "add an item to the hash" means, let alone what "go back and remove/do something from/with item from the hash" is. A concrete example would be very useful.

Upvotes: 1

Related Questions