-1

How can I generate a thread dynamically in an efficient and controlled manner? The threads are to be created dynamically based on each XML host id.

Example:

samplethread1  for hostid:-1
samplethread2  for hostid:-2

Because I cannot rely on the host id count I need to make my code dynamic: suggest how I can have a control on each thread.

Given a piece of sample XML code:

<?xml version="1.0" standalone="yes"?>
  <HOSTS>
     <Host id = '1'>
       <Extension>txt</Extension>
       <FolderPath>C:/temp</FolderPath>
     </Host>
     <Host id = '2'>
       <Extension>rar</Extension>
       <FolderPath>C:/Sample</FolderPath>
     </Host>
  </HOSTS>
pb2q
  • 54,061
  • 17
  • 135
  • 139
user1300588
  • 53
  • 1
  • 3
  • 9

2 Answers2

4

I have to agree that the question is not particularly clear. But if you are looking to just create a new thread for every host, then how about this? This is using the .NET 4.0 Task Parallel Library. From .NET 4.0 onwards this is an easy way to harness the concurrent capabilities of your processor.

static void Main(string[] args)
{
    var currentDir = Directory.GetCurrentDirectory();
    var xDoc = XDocument.Load(string.Format(Path.Combine(currentDir, "Hosts.xml")));
    var taskFactory = new TaskFactory();

    foreach (XElement host in xDoc.Descendants("Host"))
    {
        var hostId = (int) host.Attribute("id");
        var extension = (string) host.Element("Extension");
        var folderPath = (string) host.Element("FolderPath");
        taskFactory.StartNew(() => DoWork(hostId, extension, folderPath));
    }
    //Carry on with your other work
}

static void DoWork(int hostId, string extension, string folderPath)
{
    //Do stuff here
}

If you're using .NET 3.5 or previous, then you can just create the threads yourself:

static void Main(string[] args)
{
    var currentDir = Directory.GetCurrentDirectory();
    var xDoc = XDocument.Load(string.Format(Path.Combine(currentDir, "Hosts.xml")));
    var threads = new List<Thread>();

    foreach (XElement host in xDoc.Descendants("Host"))
    {
        var hostID = (int) host.Attribute("id");
        var extension = (string) host.Element("Extension");
        var folderPath = (string) host.Element("FolderPath");
        var thread = new Thread(DoWork)
                         {
                             Name = string.Format("samplethread{0}", hostID)
                         };
        thread.Start(new FileInfo
                         {
                             HostId = hostID,
                             Extension = extension,
                             FolderPath = folderPath
                         });
        threads.Add(thread);
    }
    //Carry on with your other work, then wait for worker threads
    threads.ForEach(t => t.Join());
}

static void DoWork(object threadState)
{
    var fileInfo = threadState as FileInfo;
    if (fileInfo != null)
    {
        //Do stuff here
    }
}

class FileInfo
{
    public int HostId { get; set; }
    public string Extension { get; set; }
    public string FolderPath { get; set; }
}

This for me is still the best guide to Threading.

EDIT

So this is the task based version of what I think you're getting at in your comment?

static void Main()
{
    var currentDir = Directory.GetCurrentDirectory();
    var xDoc = XDocument.Load(string.Format(Path.Combine(currentDir, "Hosts.xml")));
    var taskFactory = new TaskFactory();

    //I'm assuming this ID would normally be user input, or be passed from some other external source
    int hostId = 2;

    taskFactory.StartNew(() => DoWork(hostId, xDoc));
    //Carry on with your other work
}

static void DoWork(int hostId, XDocument hostDoc)
{
    XElement foundHostElement = (from hostElement in hostDoc.Descendants("Host")
                                    where (int)hostElement.Attribute("id") == hostId
                                    select hostElement).First();
    var extension = (string)foundHostElement.Element("Extension");
    var folderPath = (string)foundHostElement.Element("FolderPath");
    //Do stuff here
}
Mike
  • 5,797
  • 4
  • 32
  • 44
  • @micheal thank you for reply and easy understandable code, small clarification how can get the elements in dowork method based on host id? – user1300588 Jun 10 '12 at 16:09
  • @user1300588 I'm not quite sure what you mean? You just want to pass a host id to the DoWork method and then find the other elements (Extension & FolderPath) based on that? – Mike Jun 10 '12 at 18:59
  • @micheal thank u, yeah my doubt was that...now it was cleared by this post thanx a lot – user1300588 Jun 10 '12 at 19:19
  • @micheal, one doubt how can we achive parameters(hostid,extension,folderpath) in dowork method in ver3.5 sample – user1300588 Jun 11 '12 at 06:40
  • I'm not too sure I follow sorry? – Mike Jun 11 '12 at 20:25
  • @micheal it is possible to set timer for each different thread,as we are passing extension,folderpath, if we pass time parameter also,so that threads will fire based on the timing,for thread timing like ID=1 timing like 2 min,ID=2 timing as 5min can manage this?in the above code – user1300588 Jun 15 '12 at 05:11
  • @user1300588 Do you mean you want to run the thread for the amount of time specified, or you want to wait for the amount of time specified before starting? – Mike Jun 18 '12 at 14:20
  • @micheal let us assume, if the want to run this thread daily 4 clk,another 6 clk,like this way i need to fire the threads,when service start all the thread to just initialized, threads should to be work based on the timer what we have sets in the configuaration file,kindly advice please – user1300588 Jun 19 '12 at 06:23
  • @user1300588 You should probably have a search on here and if you find nothing, start a new thread - the scope of what you're asking has increased dramatically, so this question title is misleading. – Mike Jun 19 '12 at 17:58
  • @micheal, i agree your point,because of you i have got good snippet code for to create a dynamic thread with out any issues,but i just want to improve my code,let me explain my view if you any idea about that help me please,as you aware above threading pretty well,using window service application from abv xml i can able to create two threads,i want to run one thread on 5 clk and another 6 clk daily after this job done thread should not die wait for next day 5 clk and another for 6 clk ,by adding timer param in xml for two hosts,searching for this but no luck,kindly advice and help – user1300588 Jun 19 '12 at 18:16
  • Have a look [here](http://stackoverflow.com/questions/246697/windows-service-and-timer). – Mike Jun 19 '12 at 21:47
1

If you don't want to maintain the array handling an you can just "fire and forget" so i would suggest using the 'ThreadPool':

ThreadPool.QueueUserWorkItem();

More info at http://msdn.microsoft.com/en-us/library/3dasc8as(v=vs.80).aspx

if you want to create the array you can do something like:

List<Thread> threads = new List<Thread>();
threads.Add(new Thread()); //Create the thread with your parameters here

example of creating and running threads: http://msdn.microsoft.com/en-us/library/system.threading.thread.aspx

eyossi
  • 3,992
  • 18
  • 20