none
Multi-threading in javascript

    Question

  • Can any body tell me how to use the library to virtually work like threading in javascript? Code is given below...

    /********************************************************************************
     File:   System/Threading.js
     Version:  1.0.0
     Date:  2003-05-15

     f(m) Base Class Library
     A ECMAScript library to serve as the foundation
     for ECMAScript-hosted application development.
     Copyright (C) 2003 Thomas R. Trenka, Ph.D.

     This library is free software; you can redistribute it and/or
     modify it under the terms of the GNU Lesser General Public
     License as published by the Free Software Foundation; either
     version 2.1 of the License, or any later version.

     This library is distributed in the hope that it will be useful,
     but WITHOUT ANY WARRANTY; without even the implied warranty of
     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
     Lesser General Public License for more details.

     You should have received a copy of the GNU Lesser General Public
     License along with this library; if not, write to the Free Software
     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

     Simple threading library.  Provides facilities for a Timer, as well as
      a simplistic Thread/ThreadPool construct for background processing
      tasks.
    **********************************************************************************/
    Import('System.Events') ;

    if (!Environment) throw new Exception("f(m).System.Threading requires the Environment object.") ;

    var Threading = { } ;
    Threading.ThreadState = { Unstarted:-1, Stopped:0, Pending:1, Running:2, Suspended:3, Waiting:4, Finished:5 } ;
    Threading.ThreadPriority = { Lowest:1, BelowNormal:2, Normal:3, AboveNormal:4, Highest:5 } ;
    Threading.Timer = function() {
     var timer = null ;
     var interval = 1000 ;
     function bounce(src, ea) { src.Stop(); src.Start() ; }
     this.Status = Threading.ThreadState.Unstarted ;
     this.GetTick = function() { return interval ; } ;
     this.SetTick = function(n) {
      if (Math.abs(parseInt(n)) < 10)
       throw new ArgumentException("Threading.Timer.SetTick(" + n + "): value must be >= 10 (ms).") ;
      interval = Math.abs(parseInt(n)) ;
      if (this.Status == Threading.ThreadState.Running) {
       var eh = new Events.EventHandler(bounce) ;
       eh.RunOnce = true ;
       tick.Add(eh) ;
      }
     } ;
     var tick = this.OnTick = new Events.Listener().Invoke ;
     this.OnStart  = new Events.Listener().Invoke ;
     this.OnSuspend  = new Events.Listener().Invoke ;
     this.OnResume  = new Events.Listener().Invoke ;
     this.OnStop  = new Events.Listener().Invoke ;
     this.Start = function() {
      if (this.OnStart) this.OnStart({ type:"onStart" }) ;
      this.Status = Threading.ThreadState.Running ;
      timer = (Environment.GetHost()).setInterval(tick, interval) ;
     } ;
     this.Stop = function() {
      if (this.OnStop) this.OnStop({ type:"onStop" }) ;
      this.Status = Threading.ThreadState.Stopped ;
      (Environment.GetHost()).clearInterval(timer) ;
     } ;
     this.Suspend = function() {
      if (this.OnSuspend) this.OnSuspend({ type:"onSuspend" }) ;
      this.Status = Threading.ThreadState.Suspended ;
      (Environment.GetHost()).clearInterval(timer) ;
     } ;
     this.Resume = function() {
      if (this.OnResume) this.OnResume({ type:"onResume" }) ;
      this.Status = Threading.ThreadState.Running ;
      timer = (Environment.GetHost()).setInterval(tick, interval) ;
     } ;
     this.Reset = function() {
      this.Status = Threading.ThreadState.Unstarted ;
      interval = 1000 ;
      this.OnStart.Reset() ;
      this.OnTick.Reset() ;
      this.OnSuspend.Reset() ;
      this.OnResume.Reset() ;
      this.OnStop.Reset() ;
     } ;
    } ;

    Threading.Thread = function(fn) {
     if (!fn)
      throw new ArgumentException("Threading.Thread(): you must supply the function for this Thread.") ;
     if (!fn.IsInstanceOf(Function))
      throw new ArgumentException("Threading.Thread(): the argument you supplied is not a Function.") ;

     var func = fn ;
     this.ThreadState = Threading.ThreadState.Unstarted ;
     this.Priority = Threading.ThreadPriority.Normal ;
     this.LastException = null ;
     this.Execute = function() {
      this.ThreadState = Threading.ThreadState.Running ;
      try {
       func(this) ;
      } catch (ex) {
       this.LastException = ex ;
      } finally {
       this.ThreadState = Threading.ThreadState.Finished ;
      }
     } ;
    } ;

    Threading.ThreadPool = function(mxthrs, intvl){
     if (this.IsInstanceOf(Threading.ThreadPool) && Threading.ThreadPool.Instantiated)
      throw new Exception("Threading.ThreadPool(): only one ThreadPool may be instantiated.") ;

     var maxThreads = (mxthrs) ? parseInt(mxthrs) : 16 ;
     var availableThreads = maxThreads ;
     var interval = (intvl) ? parseInt(intvl) : 60000;
     var fireInterval = Math.floor((interval / 2) / maxThreads) ;
     if (fireInterval < 100)
      throw new ArgumentException(
       "Threading.ThreadPool(): (interval[=="
       + interval
       + "]/2)/maxThreads[=="
       + maxThreads
       + "] must be > 100ms (currently == "
       + Math.floor((interval/2)/maxThreads)
       + "ms."
      ) ;

     var queue = [] ;
     var timers = new Array(maxThreads + 1) ;
     var timer = new Threading.Timer() ;
     var fire = function(src, ea) {
      var tracker = timers[0] = {} ;
      for (var i = 1; i < timers.length; i++) {
       (Environment.GetHost()).clearTimeout(timersIdea) ;
       var thread = queue.shift() ;
       if (typeof(thread) == "undefined") break ;
       tracker["thread-"+i] = thread ;
       timersIdea = (Environment.GetHost()).setTimeout(thread.Execute, (fireInterval * i)) ;
      }
      availableThreads = maxThreads - (i - 1) ;
     } ;

     this.GetMaxThreads = function() { return maxThreads ; }
     this.GetAvailableThreads = function() { return availableThreads ; } ;
     this.GetTickInterval = function() { return interval ; } ;
     this.QueueUserWorkItem = function(thr) {
      if (!thr.IsSubTypeOf(Threading.Thread))
       throw new ArgumentException(
        "Threading.ThreadPool.QueueUserWorkItem(): the passed argument is not a Thread object."
       ) ;
      var idx = queue.length ;
      for (var i = 0; i < queue.length; i++) {
       if (queueIdea.Priority < thr.Priority) {
        idx = i ;
        break ;
       }
      }
      if (idx < queue.length) queue.splice(idx,0,thr) ;
      else queue.push(thr) ;
      return true ;
     } ;
     this.RemoveQueuedUserWorkItem = function(thr) {
      var idx = -1 ;
      for (var i = 0; i < queue.length; i++) {
       if (queueIdea == thr) {
        idx = i ;
        break ;
       }
      }
      if (idx > -1) {
       queue.splice(idx,1) ;
       return true ;
      }
      return false ;
     } ;
     this.Start = function(){ timer.Start() ; } ;
     this.Stop = function(){ timer.Stop() ; } ;
     this.Abort = function() {
      this.Stop() ;
      for (var i = 1; i < timers.length; i++) {
       if (timersIdea)
        (Environment.GetHost()).clearTimeout(timersIdea) ;
      }
      for (var thr in timers[0])
       this.QueueUserWorkItem(thr) ;
      timers[0] = {} ;
     } ;
     this.Reset = function() {
      this.Abort() ;
      queue = [] ;
     } ;
     this.Sleep = function(interval) {
      timer.Suspend() ;
      (Environment.GetHost()).setTimeout(timer.Resume, interval) ;
     } ;
     timer.OnTick.Add(new Events.EventHandler(fire)) ;

     // set up the static properties
     Threading.ThreadPool.__Current__ = this ;
     Threading.ThreadPool.Instantiated = true ;
    } ;
    Threading.ThreadPool.Instantiated = false ;
    Threading.ThreadPool.GetCurrent = function() {
     if (!Threading.ThreadPool.Instantiated)
      Threading.ThreadPool.__Current__ = new Threading.ThreadPool() ;
     return Threading.ThreadPool.__Current__ ;
    } ;

    Friday, February 03, 2006 7:15 AM

Answers

  • <script type="text/javascript" src="fm/system.js"></script>
    <script type="text/javascript">
     // place the Import method invoking block in a respective <SCRIPT>
     // html element to insure the web browser synchronously load js file(s).
     Import("System.Threading");
    </script>
    <script type="text/javascript">
     function fn(){
      // do something here
     }
     
     var t = new Threading.Thread(fn);
     t.Execute();
    </script>

    Monday, February 06, 2006 11:07 AM

All replies

  • namespace (System.)Threading

    The (System.)Threading namespace provides the facilities for both a Timer and a faux-Thread/ThreadPool construct. Use the Timer class when you need something that fires at regular intervals (such as an animation or clock); use the Thread and ThreadPool classes when you need the ability to start background processes.

    enumeration Threading.ThreadState

    Unstarted, Stopped, Pending, Running, Suspended, Waiting, Finished.

    enumeration Threading.ThreadPriority

    Lowest, BelowNormal, Normal, AboveNormal, Highest.

    class Threading.Timer

    The Timer class provides an object-oriented timer mechanism. It (like all the classes in the Threading namespace) is based on the use of Host.setTimeout/setInterval. In addition to fields, the Timer class supports a number of events; see below for details.

    new Threading.Timer()
    Creates a new instance of the Timer class.
    Threading.ThreadState Status
    Returns the current status of the Timer.
    GetTick()
    returns int
    Returns the current interval used by the Timer, in milliseconds.
    SetTick(int n)
    returns void
    Sets the current interval, in milliseconds, used by the Timer. If the Timer is running, the interval will be changed on the next OnTick event.
    Start()
    returns void
    Starts the timer.
    Stop()
    returns void
    Stops the timer.
    Suspend()
    returns void
    Suspends the timer; the timer can be resumed by using Resume().
    Resume()
    returns void
    Resumes a suspended timer.
    Reset()
    returns void
    Resets the timer to its initial state; the interval is reset to its default (1000 ms) as well.
    Events.Listener OnTick, OnStart, OnStop, OnSuspend, OnResume
    Standard event handlers (i.e. new Events.EventHandler(fn)) can be attached to any of these event listeners; see Events for details.

    class Threading.Thread

    The Thread class acts as a wrapper for any functions you would like executed in a background process.

    new Threading.Thread(Function fn)
    The function passed as the sole argument should take one parameter—a reference to the Thread object firing the function.
    Threading.ThreadState ThreadState
    The current state of the Thread.
    Threading.ThreadPriority Priority
    The priority of the Thread; a higher priority will cause a ThreadPool to execute this Thread before other Threads of lower priority.
    Exception LastException
    The last exception thrown during the course of the Thread's execution.
    Execute()
    returns void
    Executes the Thread's inner function. All exceptions are handled; if an exception is thrown during the course of execution, a reference to the exception will be placed in the LastException property.

    class Threading.ThreadPool

    The ThreadPool class acts as the engine which fires any threads added to the pool. Only one ThreadPool can ever be instantiated at a time.

    new Threading.ThreadPool([int mxthrs, [int intvl]])
    Parameter mxthrs indicates the maximum number of threads to be executed at any one time in the ThreadPool; if omitted, the default of 16 is used. Similarly, intvl sets the default firing interval for the ThreadPool; if omitted, the default value of 60000 ms (1 minute) is used. If passing an interval, set it to be fairly high.
    static Threading.ThreadPool.GetCurrent()
    Returns a reference to the current ThreadPool; if there are none, returns a new instance of ThreadPool. Use this method to get a reference to a ThreadPool as opposed to the constructor; the ThreadPool class was designed as based on a Singleton pattern. Note that the static method GetCurrent instantiates a ThreadPool object using the default parameters.
    GetMaxThreads()
    returns int
    Returns the maximum number of threads to be executed during every timer iteration of the ThreadPool.
    GetAvailableThreads()
    returns int
    Returns the current number of available thread slots within the ThreadPool.
    GetTickInterval()
    returns int
    Returns the interval at which each iteration of the ThreadPool's execution is fired.
    QueueUserWorkItem(Threading.Thread thr)
    returns boolean
    Adds a Thread object to the current internal thread pool.
    RemoveQueuedUserWorkItem(Threading.Thread thr)
    returns boolean
    Removes the passed Thread object from the current work queue, if found.
    Start()
    returns void
    Starts the ThreadPool execution.
    Stop()
    returns void
    Stops the ThreadPool execution.
    Abort()
    returns void
    Aborts all threads currently pending execution, and stops the ThreadPool. If there are threads in the queue, Abort will requeue those threads.
    Reset()
    returns void
    Aborts the ThreadPool and resets it to its initial state; any threads waiting to be executed will be dropped from the execution queue.
    Sleep(int int)
    returns void
    Suspends execution of the ThreadPool for int milliseconds.

     

    Sunday, February 05, 2006 7:09 AM
  • Hi,

            Can you give me an example code in javascript in which you use Threading namespace?

     

    Please try it..

    Mudassar Majeed

    Monday, February 06, 2006 4:48 AM
  • <script type="text/javascript" src="fm/system.js"></script>
    <script type="text/javascript">
     // place the Import method invoking block in a respective <SCRIPT>
     // html element to insure the web browser synchronously load js file(s).
     Import("System.Threading");
    </script>
    <script type="text/javascript">
     function fn(){
      // do something here
     }
     
     var t = new Threading.Thread(fn);
     t.Execute();
    </script>

    Monday, February 06, 2006 11:07 AM
  • Please send me the running example on mudassarm30@yahoo.com
    Monday, February 06, 2006 2:33 PM
  • great ! i'd like have it too, please please Big Smile skrosoft@hotmail.com
    Saturday, May 26, 2007 12:15 AM
  • Hey thats gr8

     

    But can u send me the running code..at pamya4u@gmail.com

     

    Thanks and Regards

     

    Pramod. 

    Wednesday, July 11, 2007 12:24 PM
  • great ! i'd like have it too, please please thitin_c@hotmail.com

     

    thank you

     

    Wednesday, August 01, 2007 7:54 AM
  •  

    Wow !!! , can u please send it to me too... I'd like to have it..., please send to mcalvinbautista@yahoo.com.

     

    thank you...

    Wednesday, October 17, 2007 2:37 PM
  • Yikes.

    Gentlemen: this is not (I repeat NOT) an Microsoft JS library, but something I wrote back in 2003 as part of the long-defunct f( m ) project, the aim of which was to bring .NET/C#-like structure to pure ECMAScript.

    Again, it's defunct, and has been for a long time.

    If you're still interested in some sort of pure JavaScript construct that will enable you to run "background processes" (and I use the term here lightly and somewhat jokingly, since JS is single-threaded, always has been and probably always will be), you can take a look at the Dojo Toolkit, of which both of these objects (Timer and ThreadPool) have been ported:

    http://archive.dojotoolkit.org/nightly/checkout/dojox/timing/

    The Dojo Toolkit (http://dojotoolkit.org) is a server-agnostic JS library, and is the successor in many ways to f( m ); I highly suggest that if you're interested in doing things like this, you take a look at it.

    regards,
    Thomas R. Trenka, Ph.D.
    Project Lead, DojoX (currently on sabbatical)
    Saturday, December 29, 2007 6:02 PM
  • The best javascript multi threading exercise I have come across so far is

    Real Javascript Multithreading Using iFrames


    Practical and no rubbish
    Monday, December 21, 2009 3:58 AM