2

I have a program, that takes long time to initialize but it's execution is rather fast.

It's becoming a bottleneck, so I want to start multiple instances of this program (like a pool) having it already initialized, and the idea is to just pass the needed arguments for it's execution, saving all the initialization time.

The problem is that I only found howto start new processes passing arguments:
How to pass parameters to ThreadStart method in Thread?

but I would like to start the process normally and then be able to communicate with it to send each thread the needed paramenters required for it's execution.

The best aproach I found was to create multiple threads where I would initialize the program and then using some communication mechanism (named pipes for example as it's all running in the same machine) be able to pass those arguments and trigger the execution of the program (one of the triggers could break an infinite loop, for example).

I'm asking if anyone can advice a more optimal solution rather that the one I came up with.

Community
  • 1
  • 1
Ptolomeo XII
  • 107
  • 1
  • 9
  • 2
    We don't really know what your solution is because you have not shown us the code for it. Basically passing parameters to a thread can be done through common data variables. You typically use a mutex of some sort to govern access to those variables. In your case that might not even be necessary if you are only reading the data in one thread and writing it in another. – o_weisman Apr 01 '15 at 11:34

2 Answers2

3

I suggest you don't mess with direct Thread usage, and use the TPL, something like this:

foreach (var data in YOUR_INITIALIZATION_LOGIC_METHOD_HERE)
{
    Task.Run(() => yourDelegate(data), //other params here);
}

More about Task.Run on MSDN, Stephen Cleary blog

VMAtm
  • 27,943
  • 17
  • 79
  • 125
2

Process != Thread

A thread lives inside a process, while a process is an entire program or service in your OS.

If you want to speed-up your app initialization you can still use threads, but nowadays we use them on top of Task Parallel Library using the Task Asynchronous Pattern.

In order to communicate tasks (usually threads), you might need to implement some kind of state machine (some kind of basic workflow) where you can detect when some task progress and perform actions based on task state (running, failed, completed...).

Anyway, you don't need named pipes or something like that to communicate tasks/threads as everything lives in the same parent process. That is, you need to use regular programming approaches to do so. I mean: use C# and thread synchronization mechanisms and some kind of in-app messaging.

Some very basic idea...

.NET has a List<T> collection class. You should design a coordinator class where you might add some list which receives a message class (designed by you) like this:

public enum OperationType { DataInitialization, Authentication, Caching }

public class Message 
{
    public OperationType Operation { get; set; }
    public Task Task { get; set; }
}

And you start all parallel initialization tasks, you add everyone to a list in the coordinator class:

Coordinator.Messages.AddRange
(
    new List<Message> 
    {
         new Message 
         { 
             Operation = Operation.DataInitialization, 
             Task = dataInitTask
         },
         ..., // <--- more messages
    }
);

Once you've added all messages with pending initialization tasks, somewhere in your code you can wait until initialization ends asynchronously this way:

// You do a projection of each message to get an IEnumerable<Task>
// to give it as argument of Task.WhenAll
await Task.WhenAll(Coordinator.Messages.Select(message => message.Task));

While this line awaits to finish all initialization, your UI (i.e. the main thread) can continue to work and show some kind of loading animation or who knows what (whatever).

Perhaps you can go a step further, and don't wait for all but wait for a group of tasks which allow your users to start using your app, while other non-critical tasks end...

Matías Fidemraizer
  • 63,804
  • 18
  • 124
  • 206