void view_ProcessImage(object sender, ProcessThreadNumberEventArgs e)
        {
            ValidationResults results            = Validation.Validate <ProjectSetting>(ps);
            List <string>     validationMessages = new List <string>();

            if (!results.IsValid)
            {
                foreach (ValidationResult vr in results)
                {
                    if (vr.Tag == "Warning")
                    {
                        if (!View.DisplayWarning(vr.Message))
                        {
                            // if user chooses not to continue with warning message, then it is treated as error.
                            validationMessages.Add(vr.Message);
                        }
                    }
                    else
                    {
                        validationMessages.Add(vr.Message);
                    }
                }
            }

            if (validationMessages.Count > 0)
            {
                SetErrorMessage(validationMessages.ToArray());
            }
            else
            {
                this.processing = true;

                System.Diagnostics.Debug.WriteLine("Current Thread: "
                                                   + Thread.CurrentThread.ManagedThreadId
                                                   + " Culture: "
                                                   + Thread.CurrentThread.CurrentCulture.ToString()
                                                   + " before processing.");

                //e.DateTimeFormat = checkDateTimeFormatString(e.DateTimeFormat
                BehaviorSetting bs = new BehaviorSetting()
                {
                    ThreadNumber         = e.ThreadNumber,
                    DateTimeFormatString = checkDateTimeFormatString(e.DateTimeFormat, GetDateTimeFormatStrings())
                };

                // we need to use WaitAll to be notified all jobs from all threads are done,
                // WaitAll will block the current thread, I don't want it happen to main thread,
                // that is the reason we create another thread instead.
                Thread controlThread = new Thread(new ParameterizedThreadStart(engineController));
                // in the situation to use command line to load different culture other than OS' current one,
                // the default culture of new thread will be from OS. We should overwrite it from main thread.
                controlThread.CurrentCulture = Thread.CurrentThread.CurrentCulture;
                controlThread.Start(bs);
            }
        }
        private void MakeCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            ProcessThreadNumberEventHandler handlers = ProcessImage;

            if (handlers != null)
            {
                //this.processing = true;
                this.Progress.Value = 0;
                uint threadNumber;
#if DEBUG
                threadNumber = 1;
#else
                threadNumber = (uint)Environment.ProcessorCount;
#endif
                ProcessThreadNumberEventArgs args = new ProcessThreadNumberEventArgs(threadNumber,
                                                                                     Properties.Settings.Default.DateTimeFormatString);
                handlers(this, args);
            }
        }