954,525 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Threading with timer

Hi,

I have to do multithreading. In my case each thread should run in a specified timer interval given in a database. I tried a sample by storing the data in an xml file and reading them with linq to xml. But it seems all the thread takes the last specified time interval in the xml file.

Let me try to explain the scenario a bit.
I have two records in xml file and for each I have set the timer interval value as 10 second and 20 second. Now when I run the thread, first time both executes imediatly and thereafter it takes timer interval as 20 for both the threads.

Please see below my codes:

my xml file:

<StoresList>
  <Store>
    <StoreListName>FIRST STORE</StoreListName>
    <StoreListDescription>Testggggggg</StoreListDescription>
    <ElapsTime>10000</ElapsTime>
  </Store>
  <Store>
    <StoreListName>SECOND STORE</StoreListName>
    <StoreListDescription>Test2</StoreListDescription>
    <ElapsTime>20000</ElapsTime>
  </Store>

A class:

public class StoreList
    {
        public string ListName { get; set; }
        public string ListDescription { get; set; }
        public string ElapsTime { get; set; }
    }


Main method:

static void Main(string[] args)
        {
            timer = new System.Timers.Timer(5000);
            timer.AutoReset = true;
            timer.Elapsed += new ElapsedEventHandler(DownloadFiles);
            timer.Start();
            Console.ReadLine();
        }
private static void DownloadFiles(object sender, ElapsedEventArgs e)
        {
            XDocument readStorelist = LoadStoreList();
            IEnumerable<StoreList> storeList = 
            from stList in readStorelist.Descendants("Store")
               select new StoreList
               {
                   ListName = stList.Element("StoreListName").Value,
                   ListDescription = stList.Element("StoreListDescription").Value,
                   ElapsTime = stList.Element("ElapsTime").Value
               };
            foreach (StoreList strList in storeList)
            {
                Thread th = new Thread(DoWrok);
                th.Start(strList);
            }
        }
 private static void DoWrok(object stList)
        {
            StoreList storeList = (StoreList)stList;
            timer.Interval = Convert.ToDouble(storeList.ElapsTime);
            Console.WriteLine();
            Console.WriteLine(DateTime.Now.ToString() + " STORE NAME: " + storeList.ListName);
            Console.WriteLine("Store list description: " + storeList.ListDescription);
        }

Can someone tell me how can I call each thread with different timer interval.

Thanks, this forum has been great help for me.

Regards,
Suraj

surajrai
Newbie Poster
16 posts since May 2010
Reputation Points: 10
Solved Threads: 1
 

Can you replace

Thread th = new Thread(DoWrok);
th.Start(strList);

by

ThreadStart thrdStrt = new ThreadStart(methodName); //void method without parameters 
Thread th = new Thread(thrdStrt);
th.Start(params...);

Please debug your code to know where the problem is.

Ramy Mahrous
Postaholic
2,196 posts since Aug 2006
Reputation Points: 480
Solved Threads: 276
 

Hi Ramy,

Thanks for your quick reply.
I have done that by instantiating new timer in each thread.
Just few more queries...
I am new to threading. Just wanted few suggesstion from you like
what are the things I have to take care while doing like this.

Please take some time to go through my post regarding my problem definition:

http://www.daniweb.com/forums/thread285395.html

Thanks a lot.

Regards, Suraj

surajrai
Newbie Poster
16 posts since May 2010
Reputation Points: 10
Solved Threads: 1
 

Nothing more consistency... ensure that your shared object if exists is consistant by i.e using Lock

Ramy Mahrous
Postaholic
2,196 posts since Aug 2006
Reputation Points: 480
Solved Threads: 276
 

I would flip this design around a little bit. Creating a timer consumes resources so instead of creating 6 timers for 6 cameras, creating 1 timer and have it launch the download code in another thread. I would also recommend using threadpool threads instead of manually creating a thread. Here is a stub class for this type of design:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Timer = System.Threading.Timer;

namespace daniweb
{
  public class IPCamera
  {
    private readonly object locker = new object();
    //
    public int DownloadInterval { get; set; }
    public DateTime LastDownload { get; set; }
    //
    public bool NeedToDownload
    {
      get
      {
        return
          (TimeSinceLastDownload == TimeSpan.Zero) ||
          (LastDownload == DateTime.MinValue) ||
          (TimeSinceLastDownload.TotalSeconds >= DownloadInterval);
      }
    }
    public TimeSpan TimeSinceLastDownload
    {
      get
      {
        return DateTime.Now.Subtract(LastDownload);
      }
    }
    //
    public IPCamera()
    {
      LastDownload = DateTime.Today.AddDays(-1); //Just give it an arbitrary older date to prevent exceptions when calculating timespans
    }

    public void DownloadImages()
    {
      System.Threading.Thread.Sleep(1000 * 60 * 3); //3 minutes, simulate delay
      LastDownload = DateTime.Now;
    }
  }
  public class IPCameraWatcher : IDisposable
  {
    private List<IPCamera> lst;
    private readonly Timer timer;

    public IPCameraWatcher()
    {
      lst = new List<IPCamera>();
      timer = new Timer(callback, null, 0, 1000); //Run the timer every 1 second
    }

    private int syncPoint;
    private void callback(object state)
    {
      int sync = Interlocked.CompareExchange(ref syncPoint, 1, 0);
      if (sync != 0) return; //The timer is still busy from the last elapsed event
      try
      {
        foreach (var camera in lst)
        {
          if (camera.NeedToDownload)
          {
            ThreadPool.QueueUserWorkItem(s => camera.DownloadImages()); //Run in another thread
          }
        }
      }
      finally
      {
        //Need to use Interlocked since we're not in a synchronized code block, and not using a volatile member
        Interlocked.Exchange(ref syncPoint, 0);
      }
    }

    #region IDisposable Members

    public void Dispose()
    {
      timer.Dispose();
    }

    #endregion
  }
}
sknake
Industrious Poster
4,954 posts since Feb 2009
Reputation Points: 1,764
Solved Threads: 735
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You