Exemple #1
0
 /// <summary>
 /// Posts a custom message back to the parent thread
 /// </summary>
 /// <param name="msg">The custom object to send as the message</param>
 public void PostMessage(object msg)
 {
     if (!WorkerThreadManager.IsWebWorker())
     {
         // Send the result back to the main thread
         _worker.PostMessage(
             // Create a new WebWorkerMessage
             new WorkerThreadManager.WebWorkerMessage
         {
             // The message is a finish message
             MsgType = WorkerThreadManager.MessageTypeMessage,
             // Set the data to a new WebWorkerFinishMessage
             Data = msg
         }
             );
     }
     else
     {
         WorkerThreadManager.PostMessage(msg);
     }
 }
Exemple #2
0
        /// <summary>
        /// Start the specified static function in the Web Worker with param passed to the function.
        /// On completion of the function, it should return a result which is then sent in the main thread to the
        /// specified onResult callback.
        /// </summary>
        /// <param name="entryPoint">The entry point (as a string) representing the function to start in the web worker</param>
        /// <param name="param">The parameter to be sent to the function when it is started</param>
        /// <param name="onResult">The callback to be called when the function finishes, callback format is (this thread, the initial parameter, the result from the function)</param>
        public void Start(string entryPoint, object param, Action <Thread, object, object> onResult = null)
        {
            // First we must make sure the function exists and is static
            object threadStartRef;

            try
            {
                // Try to get a reference to the entry point
                threadStartRef = WorkerThreadManager.GetObjectRefFromString(Script.Get <object>("window"), entryPoint);
                // Confirm that it is not null
                if (threadStartRef == null)
                {
                    // The reference was null
                    throw new Exception();
                }
                // Confirm that the reference is a function
                if (!Script.Write <bool>("typeof threadStartRef === 'function'"))
                {
                    // The reference is not a function
                    throw new Exception();
                }
            }
            catch (Exception)
            {
                // The entry point is not valid, it either does not exist or is not a static function
                throw new ArgumentException("Thread entry point " + entryPoint + " doesn't seem to exist, or is not a static function");
            }

            // Check that this thread is not already dead
            if (_isDead)
            {
                // Thread is dead, can't start any my functions
                throw new InvalidOperationException("Attempt made to call Start on a dead thread");
            }

            // Can only run one thread start if there is no on result callback
            if (onResult == null && _queuedStarts.Any())
            {
                // Whoops
                throw new InvalidOperationException("Attempt made to queue thread starts with no valid OnResult handler");
            }

            // Ask the worker to start the thread if web workers are available
            if (_worker != null)
            {
                // Ask the worker to start (or queue) this function
                _worker.PostMessage(
                    // Send a new message
                    new WorkerThreadManager.WebWorkerMessage
                {
                    // The message is to start a function
                    MsgType = WorkerThreadManager.MessageTypeStart,
                    // The data is a WebWorkerStartMessage
                    Data = new WorkerThreadManager.WebWorkerStartMessage
                    {
                        // Set the thread id
                        ThreadId = _globalThreadIdCounter,
                        // Set the entry point
                        ThreadEntryPoint = entryPoint,
                        // Set the parameter
                        ThreadParam = param
                    }
                }
                    );
                // Add the thread to the queue of thread starts
                _queuedStarts.Add(_globalThreadIdCounter,
                                  // Create a new QueuedThreadStart object
                                  new QueuedThreadStart
                {
                    // Set the thread id
                    ThreadId = _globalThreadIdCounter,
                    // Set the original parameter
                    Param = param,
                    // Set the on result callback
                    OnResult = onResult
                }
                                  );
            }
            else
            {
                // Web workers are not available, run the thread start function in this thread

                // Set the current thread to be the current global thread count
                _currentThreadId = _globalThreadIdCounter;

                // Try to call the function
                try
                {
                    // Call the function with the parameter, and get the result
                    var result = Script.Write <object>("threadStartRef(param)", threadStartRef, param);

                    // Check if an on result callback was provided
                    if (onResult != null)
                    {
                        // Yes, call the handler with this thread, the original parameter and the result from the message
                        onResult(this, param, result);
                    }
                    else
                    {
                        // No, set the internal result to the result from the message
                        Result = result;
                    }
                }
                catch (Exception e)
                {
                    // An exception occurred running the thread start function
                    // Continue raising the exception in this thread so it is printed to the console
                    throw new Exception("Unhandled exception in thread (" + _currentThreadId + ")", e);
                }
                finally
                {
                    // Always go back to the main thread
                    _currentThreadId = 0;
                }
            }

            // Increment the global thread counter
            _globalThreadIdCounter++;
        }