コード例 #1
0
        public static void TestObjectDisposedException()
        {
            ThreadWorker worker = new ThreadWorker(new ProgressContext());

            worker.Work += (object sender, ThreadWorkerEventArgs e) =>
            {
                e.Result = FileOperationStatus.Success;
            };
            try
            {
                worker.Run();
                worker.Join();
            }
            finally
            {
                worker.Dispose();
            }

            bool hasCompleted = false;

            Assert.Throws <ObjectDisposedException>(() => { worker.Run(); });
            Assert.Throws <ObjectDisposedException>(() => { worker.Join(); });
            Assert.Throws <ObjectDisposedException>(() => { hasCompleted = worker.HasCompleted; });
            Assert.That(!hasCompleted, "Although the thread has completed, the variable should still be false since the attempt to set it is after Dispose().");
            Assert.DoesNotThrow(() => { worker.Dispose(); });
        }
コード例 #2
0
 public void Decrypt(Passphrase passphrase)
 {
     BTProgressHUD.Show("Opening ...", maskType: BTProgressHUD.MaskType.Gradient);
     CreateWorker();
     this.key = passphrase.DerivedPassphrase;
     worker.Run();
 }
コード例 #3
0
        public static void TestProgress()
        {
            FakeRuntimeEnvironment environment = (FakeRuntimeEnvironment)OS.Current;
            int progressCalls = 0;

            ProgressContext progress = new ProgressContext();

            using (ThreadWorker worker = new ThreadWorker(progress))
            {
                worker.Work += (object sender, ThreadWorkerEventArgs e) =>
                {
                    environment.CurrentTiming.CurrentTiming = TimeSpan.FromSeconds(1);
                    e.Progress.AddCount(1);
                    e.Result = FileOperationStatus.Success;
                };
                progress.Progressing += (object sender, ProgressEventArgs e) =>
                {
                    ++progressCalls;
                };
                worker.Run();
                worker.Join();
            }

            Assert.That(progressCalls, Is.EqualTo(1), "The Progressing event should be raised exactly one time.");
        }
コード例 #4
0
        public static void TestSimple()
        {
            int workThreadId = -1;
            FileOperationStatus returnedStatus = FileOperationStatus.UnspecifiedError;

            bool done = false;

            using (ThreadWorker worker = new ThreadWorker(new ProgressContext()))
            {
                worker.Work += (object sender, ThreadWorkerEventArgs e) =>
                {
                    workThreadId = Thread.CurrentThread.ManagedThreadId;
                    e.Result     = FileOperationStatus.Success;
                };
                worker.Completing += (object sender, ThreadWorkerEventArgs e) =>
                {
                    returnedStatus = e.Result;
                    done           = true;
                };
                worker.Run();
                worker.Join();
            }

            Assert.That(returnedStatus, Is.EqualTo(FileOperationStatus.Success), "The status should be returned as successful.");
            Assert.That(workThreadId, Is.Not.EqualTo(Thread.CurrentThread.ManagedThreadId), "The work should not be performed on the caller thread.");
            Assert.That(done, Is.True, "The background work must have executed the completed handler now.");
        }
コード例 #5
0
        public static void TestFinishInBackground()
        {
            bool            didComplete = false;
            ProgressContext progress    = new ProgressContext();

            progress.Progressing += (object sender2, ProgressEventArgs e2) =>
            {
                didComplete = true;
            };

            using (ThreadWorker threadWorker = new ThreadWorker(progress))
            {
                threadWorker.Work += (object sender, ThreadWorkerEventArgs e) =>
                {
                    using (WorkerGroup workerGroup = new WorkerGroup(progress))
                    {
                        IThreadWorker worker = workerGroup.CreateWorker();
                        worker.Work += (object sender2, ThreadWorkerEventArgs e2) =>
                        {
                            e2.Progress.NotifyLevelStart();
                            e2.Progress.NotifyLevelFinished();
                        };
                        worker.Run();
                    }
                };
                threadWorker.Run();
            }

            Assert.That(didComplete, "Execution should continue here, with the flag set indicating that the progress event occurred.");
        }
コード例 #6
0
        private void StartNotifyWorker()
        {
            lock (NoticeLocker)
            {
                if (!NotifyWorker.IsRunning)
                {
                    NotifyWorker.Run();
                }

                NotifyWorker.DoWorkAction = this.DoNotify;
                NotifyWorker.Interval     = TimelineSettings.Instance.NotifyInterval;

                isNotifyRunning = true;
            }
        }
コード例 #7
0
        public static void TestPrepare()
        {
            bool wasPrepared = false;

            using (ThreadWorker worker = new ThreadWorker(new ProgressContext()))
            {
                worker.Prepare += (object sender, ThreadWorkerEventArgs e) =>
                {
                    wasPrepared = true;
                };
                worker.Run();
                worker.Join();
            }

            Assert.That(wasPrepared, Is.True, "The Prepare event should be raised.");
        }
コード例 #8
0
        public void Initialize()
        {
            if (this.isInitialized)
            {
                return;
            }

            this.isInitialized = true;

            lock (this)
            {
                this.scanWorker = ThreadWorker.Run(
                    this.ScanEnmity,
                    100d,
                    "ScanEnmityWorker",
                    ThreadPriority.BelowNormal);
            }
        }
コード例 #9
0
        public static void TestErrorSetInWorkCompleted()
        {
            bool errorInWork = false;

            using (ThreadWorker worker = new ThreadWorker(new ProgressContext()))
            {
                worker.Work += (object sender, ThreadWorkerEventArgs e) =>
                {
                    throw new InvalidOperationException();
                };
                worker.Completing += (object sender, ThreadWorkerEventArgs e) =>
                {
                    errorInWork = e.Result == FileOperationStatus.Exception;
                };
                worker.Run();
                worker.Join();
            }

            Assert.That(errorInWork, Is.True, "The operation was interrupted by an exception and should return status as such.");
        }
コード例 #10
0
        public static void TestCancellationByException()
        {
            bool wasCanceled = false;

            using (ThreadWorker worker = new ThreadWorker(new ProgressContext()))
            {
                worker.Work += (object sender, ThreadWorkerEventArgs e) =>
                {
                    throw new OperationCanceledException();
                };
                worker.Completing += (object sender, ThreadWorkerEventArgs e) =>
                {
                    wasCanceled = e.Result == FileOperationStatus.Canceled;
                };
                worker.Run();
                worker.Join();
            }

            Assert.That(wasCanceled, Is.True, "The operation was canceled and should return status as such.");
        }
コード例 #11
0
 public static void TestHasCompleted()
 {
     using (ThreadWorker worker = new ThreadWorker(new ProgressContext()))
     {
         bool wasCompletedInWork = false;
         worker.Work += (object sender, ThreadWorkerEventArgs e) =>
         {
             wasCompletedInWork = worker.HasCompleted;
         };
         bool wasCompletedInCompleted = false;
         worker.Completing += (object sender, ThreadWorkerEventArgs e) =>
         {
             wasCompletedInCompleted = worker.HasCompleted;
         };
         worker.Run();
         worker.Join();
         Assert.That(!wasCompletedInWork, "Completion is not set as true in the work event.");
         Assert.That(!wasCompletedInCompleted, "Completion is not set as true until after the completed event.");
         Assert.That(worker.HasCompleted, "Completion should be set as true when the thread is joined.");
     }
 }
コード例 #12
0
        /// <summary>
        /// Perform a background operation with support for progress bars and cancel.
        /// </summary>
        /// <param name="displayText">A text that may be used as a reference in various messages.</param>
        /// <param name="work">A 'work' delegate, taking a ProgressContext and return a FileOperationStatus. Executed on a background thread. Not the calling/GUI thread.</param>
        /// <param name="complete">A 'complete' delegate, taking the final status. Executed on the original caller thread, typically the GUI thread.</param>
        public void BackgroundWorkWithProgress(Func <ProgressContext, FileOperationStatus> work, Action <FileOperationStatus> complete)
        {
            ProgressContext progress    = new ProgressContext();
            ProgressBar     progressBar = CreateProgressBar(progress);

            OnProgressBarCreated(new ControlEventArgs(progressBar));
            progress.Progressing += (object sender, ProgressEventArgs e) =>
            {
                progressBar.Value = e.Percent;
            };
            ThreadWorker threadWorker = new ThreadWorker(progress);

            threadWorker.Work += (object sender, ThreadWorkerEventArgs e) =>
            {
                e.Result = work(e.Progress);
            };
            threadWorker.Completing += (object sender, ThreadWorkerEventArgs e) =>
            {
                try
                {
                    complete(e.Result);
                    progressBar.Parent = null;
                }
                finally
                {
                    progressBar.Dispose();
                }
            };
            threadWorker.Completed += (object sender, ThreadWorkerEventArgs e) =>
            {
                IDisposable disposable = sender as IDisposable;
                if (disposable != null)
                {
                    disposable.Dispose();
                }
                Interlocked.Decrement(ref _workerCount);
            };
            Interlocked.Increment(ref _workerCount);
            threadWorker.Run();
        }
コード例 #13
0
        public static void TestCancellationByRequest()
        {
            bool wasCanceled = false;
            FakeRuntimeEnvironment environment = (FakeRuntimeEnvironment)OS.Current;

            using (ThreadWorker worker = new ThreadWorker(new ProgressContext()))
            {
                worker.Work += (object sender, ThreadWorkerEventArgs e) =>
                {
                    e.Progress.Cancel = true;
                    environment.CurrentTiming.CurrentTiming = TimeSpan.FromSeconds(1);
                    e.Progress.AddCount(1);
                };
                worker.Completing += (object sender, ThreadWorkerEventArgs e) =>
                {
                    wasCanceled = e.Result == FileOperationStatus.Canceled;
                };
                worker.Run();
                worker.Join();
            }

            Assert.That(wasCanceled, Is.True, "The operation was canceled and should return status as such.");
        }
コード例 #14
0
        private void InitTask()
        {
            this.dumpLogTask = ThreadWorker.Run(
                doWork,
                TimeSpan.FromSeconds(Config.Instance.WriteInterval).TotalMilliseconds,
                "XIVLog Worker",
                ThreadPriority.Lowest);

            ActGlobals.oFormActMain.OnLogLineRead -= this.OnLogLineRead;
            ActGlobals.oFormActMain.OnLogLineRead += this.OnLogLineRead;

            void doWork()
            {
                var isNeedsFlush = false;

                if (string.IsNullOrEmpty(Config.Instance.OutputDirectory) ||
                    LogQueue.IsEmpty)
                {
                    Thread.Sleep(TimeSpan.FromSeconds(Config.Instance.WriteInterval));
                    return;
                }

                if ((DateTime.Now - this.lastFlushTimestamp).TotalSeconds
                    >= Config.Instance.FlushInterval)
                {
                    isNeedsFlush = true;
                }

                if (this.currentLogfileName != this.LogfileName)
                {
                    if (this.writter != null)
                    {
                        if (this.writeBuffer.Length > 0)
                        {
                            this.writter.Write(this.writeBuffer.ToString());
                            this.writeBuffer.Clear();
                        }

                        this.writter.Flush();
                        this.writter.Close();
                        this.writter.Dispose();
                    }

                    if (!Directory.Exists(Config.Instance.OutputDirectory))
                    {
                        Directory.CreateDirectory(Config.Instance.OutputDirectory);
                    }

                    this.writter = new StreamWriter(
                        new FileStream(
                            this.LogfileName,
                            FileMode.Append,
                            FileAccess.Write,
                            FileShare.Read),
                        new UTF8Encoding(false));
                    this.currentLogfileName = this.LogfileName;

                    this.RaisePropertyChanged(nameof(this.LogfileName));
                    this.RaisePropertyChanged(nameof(this.LogfileNameWithoutParent));
                }

                XIVLog.RefreshPCNameDictionary();

                while (LogQueue.TryDequeue(out XIVLog xivlog))
                {
                    if (this.currentZoneName != xivlog.ZoneName)
                    {
                        this.currentZoneName = xivlog.ZoneName;
                        this.wipeoutCounter  = 1;
                        this.fileNo++;
                        isNeedsFlush = true;
                    }

                    if (xivlog.Log.Contains("wipeout") ||
                        xivlog.Log.Contains("の攻略を終了した。"))
                    {
                        this.wipeoutCounter++;
                        this.fileNo++;
                        isNeedsFlush = true;
                    }

                    this.writeBuffer.AppendLine(xivlog.ToCSVLine());
                    Thread.Yield();
                }

                if (isNeedsFlush ||
                    this.isForceFlush ||
                    this.writeBuffer.Length > 5000)
                {
                    this.writter.Write(this.writeBuffer.ToString());
                    this.writeBuffer.Clear();

                    if (isNeedsFlush || this.isForceFlush)
                    {
                        this.isForceFlush       = false;
                        this.lastFlushTimestamp = DateTime.Now;
                        this.writter?.Flush();
                    }
                }
            }
        }
コード例 #15
0
ファイル: XIVLogPlugin.cs プロジェクト: veedeeee/ACT.Hojoring
        private void InitTask()
        {
            // FFXIV.Framework.config を読み込ませる
            lock (FFXIV.Framework.Config.ConfigBlocker)
            {
                _ = FFXIV.Framework.Config.Instance;
            }

            var config = Config.Instance;

            // WriteIntervalの初期値をマイグレーションする
            if (config.WriteInterval >= 30)
            {
                config.WriteInterval = Config.WriteIntervalDefault;
            }

            this.dumpLogTask = ThreadWorker.Run(
                doWork,
                TimeSpan.FromSeconds(config.WriteInterval).TotalMilliseconds,
                "XIVLog Worker",
                ThreadPriority.Lowest);

            ActGlobals.oFormActMain.OnLogLineRead -= this.OnLogLineRead;
            ActGlobals.oFormActMain.OnLogLineRead += this.OnLogLineRead;

            void doWork()
            {
                var isNeedsFlush = false;

                if (string.IsNullOrEmpty(config.OutputDirectory))
                {
                    Thread.Sleep(TimeSpan.FromSeconds(config.WriteInterval));
                    return;
                }

                if (LogQueue.IsEmpty)
                {
                    if ((DateTime.Now - this.lastWroteTimestamp).TotalSeconds > 10)
                    {
                        this.lastWroteTimestamp = DateTime.MaxValue;
                        isNeedsFlush            = true;
                    }
                    else
                    {
                        if (!this.isForceFlush)
                        {
                            Thread.Sleep(TimeSpan.FromSeconds(config.WriteInterval));
                            return;
                        }
                    }
                }

                if ((DateTime.Now - this.lastFlushTimestamp).TotalSeconds
                    >= config.FlushInterval)
                {
                    isNeedsFlush = true;
                }

                if (this.currentLogfileName != this.LogfileName)
                {
                    if (this.writter != null)
                    {
                        this.writter.Flush();
                        this.writter.Close();
                        this.writter.Dispose();
                    }

                    if (!Directory.Exists(config.OutputDirectory))
                    {
                        Directory.CreateDirectory(config.OutputDirectory);
                    }

                    this.writter = new StreamWriter(
                        new FileStream(
                            this.LogfileName,
                            FileMode.Append,
                            FileAccess.Write,
                            FileShare.Read,
                            64 * 1024),
                        new UTF8Encoding(config.WithBOM));
                    this.currentLogfileName = this.LogfileName;

                    this.RaisePropertyChanged(nameof(this.LogfileName));
                    this.RaisePropertyChanged(nameof(this.LogfileNameWithoutParent));
                }

                XIVLog.RefreshPCNameDictionary();

                while (LogQueue.TryDequeue(out XIVLog xivlog))
                {
                    if (this.currentZoneName != xivlog.ZoneName)
                    {
                        this.currentZoneName = xivlog.ZoneName;
                        this.wipeoutCounter  = 1;
                        this.fileNo++;
                        isNeedsFlush = true;
                    }

                    if (StopLoggingKeywords.Any(x => xivlog.Log.Contains(x)))
                    {
                        this.wipeoutCounter++;
                        this.fileNo++;
                        isNeedsFlush = true;
                    }

                    // ログをParseする
                    xivlog.Parse();

                    this.writter.WriteLine(xivlog.ToCSVLine());
                    this.lastWroteTimestamp = DateTime.Now;
                    Thread.Yield();
                }

                if (isNeedsFlush ||
                    this.isForceFlush)
                {
                    if (isNeedsFlush || this.isForceFlush)
                    {
                        this.isForceFlush       = false;
                        this.lastFlushTimestamp = DateTime.Now;
                        this.writter?.Flush();
                    }
                }
            }
        }