private ThreadWorker<Priority, Task> InitNewWorkingThread() { var worker = new ThreadWorker<Priority,Task>(_queue); var thread = new Thread(worker.Run) {Name = "Pool thread #" + ++_threadCounter, IsBackground = true}; thread.Start(); return worker; }
public void ThreadWorkerStoresReduceResults() { var reducerCodeFileName = new Uri("file:///SampleReducer.cs"); var keys = ReducerTests.CreateTwoKeyFileSet(this.storage); TestHelpers.LoadToStorage(@"..\..\SampleReducer.cs", reducerCodeFileName, this.storage); var worker = new ThreadWorker(this.storage, 1); worker.Reduce(Base64.Encode("k1"), reducerCodeFileName); worker.Join(); var result = default(string); var regex = new Regex(string.Format("^" + Core.Properties.Settings.Default.ReduceOutputFileName + "$", @"(?<Key>.+)", "[0-9]+", RegexExtensions.GuidRegexString)); var uris = this.storage.ListFiles(); foreach (var uri in uris) { var fileName = this.storage.GetFileName(uri); if (regex.IsMatch(fileName)) { var key = regex.Match(fileName).Groups["Key"].Value; if (Base64.Decode(key) == "k1") { result = this.storage.Read(fileName); } } } result.ShouldBe("3"); }
public FixedTaskScheduler (int maxWorker, ThreadPriority priority) { workQueue = new ConcurrentQueue<Task> (); workers = new ThreadWorker [maxWorker]; for (int i = 0; i < maxWorker; i++) { workers [i] = new ThreadWorker (workers, i, workQueue, new CyclicDeque<Task> (), priority, pulseHandle); workers [i].Pulse (); } }
public void Dispose_WaitsDefinedTimeout_WhenPendingTasksTakeLonger(string workerName) { // arrange var transport = A.Fake<ITransport>(); var pipeline = A.Fake<IPipeline>(); var pipelineInvoker = A.Fake<IPipelineInvoker>(); var context = A.Fake<ThreadWorkerSynchronizationContext>(); var manager = A.Fake<ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1))); var backOff = A.Fake<IBackoffStrategy>(); var logFactory = A.Fake<IRebusLoggerFactory>(); var log = A.Fake<ILog>(); var timeout = TimeSpan.FromSeconds(5); A.CallTo(() => logFactory.GetCurrentClassLogger()) .Returns(log); // Have stuff to do A.CallTo(() => manager.HasPendingTasks) .Returns(true); // system under test var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout); // act var timer = Stopwatch.StartNew(); sut.Dispose(); timer.Stop(); // assert // assuming +- 1 second. timer.Elapsed .Should().BeCloseTo(timeout, 1000); // Must have logs A.CallTo(() => log.Warn("Not all async tasks were able to finish within given timeout of {0} seconds!", timeout.TotalSeconds)) .MustHaveHappened(); A.CallTo(() => log.Warn("Worker {0} did not stop withing {1} seconds timeout!", workerName, timeout.TotalSeconds)) .MustHaveHappened(); }
public void ThreadWorkerStoresMapResults() { var fileName = new Uri("file:///file1.txt"); var fileContent = "whatever am i i"; var mapperCodeFileName = new Uri("file:///SampleMapper.cs"); storage.Store(storage.GetFileName(fileName), fileContent); TestHelpers.LoadToStorage(@"..\..\SampleMapper.cs", mapperCodeFileName, this.storage); var worker = new ThreadWorker(this.storage, 1); worker.Map(fileName, mapperCodeFileName); worker.Join(); var fileNo = this.storage.ListFiles().Count(); fileNo.ShouldBe(6); }
public ThreadWorker (ThreadWorker[] others, int workerPosition, IProducerConsumerCollection<Task> sharedWorkQueue, IConcurrentDeque<Task> dDeque, ThreadPriority priority, ManualResetEvent handle) { this.others = others; this.dDeque = dDeque; this.sharedWorkQueue = sharedWorkQueue; this.workerLength = others.Length; this.workerPosition = workerPosition; this.waitHandle = handle; this.threadPriority = priority; this.adder = new Action<Task> (ChildWorkAdder); InitializeUnderlyingThread (); }
public void Start(ProgressBox progress) { Queue <ThreadWorker> threadQueue = new Queue <ThreadWorker>(); for (int i = 0; i < databases.Count; i++) { string database = databases[i]; ThreadWorker _worker = new ThreadWorker() { WorkerReportsProgress = true }; _worker.DoWork += StartScan; _worker.ProgressChanged += progress.ProgressChanged; threadQueue.Enqueue(_worker); } SqlConnection connection = Connection.Create(host, ConnectionType.DefaultDatabase); foreach (var _worker in threadQueue) { _worker.RunWorkerCompleted += progress.FinishScan; if (!canceled) { try { connection.Open(); currentWorker = _worker; _worker.RunWorkerAsync(); } finally { connection.Close(); } } } OnFinish(); }
public async Task Stop_Logs_WhenOperationCanceledExceptionOccuresInTransport(string workerName) { // arrange var transport = A.Fake<ITransport>(); var pipeline = A.Fake<IPipeline>(); var pipelineInvoker = A.Fake<IPipelineInvoker>(); var context = A.Fake<ThreadWorkerSynchronizationContext>(); var manager = A.Fake<ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1))); var backOff = A.Fake<IBackoffStrategy>(); var logFactory = A.Fake<IRebusLoggerFactory>(); var log = A.Fake<ILog>(); var timeout = TimeSpan.FromSeconds(10); A.CallTo(() => logFactory.GetCurrentClassLogger()) .Returns(log); A.CallTo(() => transport.Receive(A<ITransactionContext>._, A<CancellationToken>._)) .Throws(() => new OperationCanceledException("test")); // system under test var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout); // act await Task.Delay(TimeSpan.FromSeconds(5)); sut.Stop(); // assert A.CallTo(() => log.Warn("Execution cancelled.")) .MustHaveHappened(); }
private static void StartUpCode(ThreadWorker e) { RepairStatus.InitStatusCheck(); Settings.rvSettings = Settings.SetDefaults(); DB.Read(e); }
public abstract object CreateThread(ThreadWorker worker, object argument = null, bool isBackground = true, bool isStart = true);
// Almost same as above but with an added predicate and treating one item at a time. // It's used by Scheduler Participate(...) method for special waiting case like // Task.WaitAll(someTasks) or Task.WaitAny(someTasks) // Predicate should be really fast and not blocking as it is called a good deal of time // Also, the method skip tasks that are LongRunning to avoid blocking (Task are not LongRunning by default) public static void ParticipativeWorkerMethod (Task self, ManualResetEventSlim predicateEvt, int millisecondsTimeout, IProducerConsumerCollection<Task> sharedWorkQueue, ThreadWorker[] others, ManualResetEvent evt, Func<Task, Task, bool> checkTaskFitness) { const int stage1 = 5, stage2 = 0; int tries = 50; WaitHandle[] handles = null; Watch watch = Watch.StartNew (); if (millisecondsTimeout == -1) millisecondsTimeout = int.MaxValue; bool aggressive = false; bool hasAutoReference = autoReference != null; Action<Task> adder = null; while (!predicateEvt.IsSet && watch.ElapsedMilliseconds < millisecondsTimeout && !self.IsCompleted) { // We try to execute the self task as it may be the simplest way to unlock // the situation if (self.Status == TaskStatus.WaitingToRun) { self.Execute (hasAutoReference ? autoReference.adder : (Action<Task>)null); if (predicateEvt.IsSet || watch.ElapsedMilliseconds > millisecondsTimeout) return; } Task value; // If we are in fact a normal ThreadWorker, use our own deque if (hasAutoReference) { var enumerable = autoReference.dDeque.GetEnumerable (); if (adder == null) adder = hasAutoReference ? autoReference.adder : (Action<Task>)null; if (enumerable != null) { foreach (var t in enumerable) { if (t == null) continue; if (checkTaskFitness (self, t)) t.Execute (adder); if (predicateEvt.IsSet || watch.ElapsedMilliseconds > millisecondsTimeout) return; } } } int count = sharedWorkQueue.Count; // Dequeue only one item as we have restriction while (--count >= 0 && sharedWorkQueue.TryTake (out value) && value != null) { evt.Set (); if (checkTaskFitness (self, value) || aggressive) value.Execute (null); else { if (autoReference == null) sharedWorkQueue.TryAdd (value); else autoReference.dDeque.PushBottom (value); evt.Set (); } if (predicateEvt.IsSet || watch.ElapsedMilliseconds > millisecondsTimeout) return; } // First check to see if we comply to predicate if (predicateEvt.IsSet || watch.ElapsedMilliseconds > millisecondsTimeout) return; // Try to complete other work by stealing since our desired tasks may be in other worker ThreadWorker other; for (int i = 0; i < others.Length; i++) { if ((other = others [i]) == autoReference || other == null) continue; if (other.dDeque.PopTop (out value) == PopResult.Succeed && value != null) { evt.Set (); if (checkTaskFitness (self, value) || aggressive) value.Execute (null); else { if (autoReference == null) sharedWorkQueue.TryAdd (value); else autoReference.dDeque.PushBottom (value); evt.Set (); } } if (predicateEvt.IsSet || watch.ElapsedMilliseconds > millisecondsTimeout) return; } /* Waiting is split in 4 phases * - until stage 1 we simply yield the thread to let others add data * - between stage 1 and stage2 we use ManualResetEventSlim light waiting mechanism * - after stage2 we fall back to the heavier WaitHandle waiting mechanism * - if really the situation isn't evolving after a couple of sleep, we disable * task fitness check altogether */ if (--tries > stage1) Thread.Yield (); else if (tries >= stage2) predicateEvt.Wait (ComputeTimeout (5, millisecondsTimeout, watch)); else { if (tries == stage2 - 1) handles = new [] { predicateEvt.WaitHandle, evt }; System.Threading.WaitHandle.WaitAny (handles, ComputeTimeout (1000, millisecondsTimeout, watch)); if (tries == stage2 - 10) aggressive = true; } } }
public static CHDManCheck ChdmanCheck(string filename, ThreadWorker thWrk, out string result) { _thWrk = thWrk; _result = ""; _resultType = CHDManCheck.Unset; string chdExe = "chdman.exe"; if (Settings.IsUnix) { chdExe = "chdman"; } string chdPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, chdExe); if (!File.Exists(chdPath)) { result = chdExe + " Not Found."; return(CHDManCheck.ChdmanNotFound); } if (!File.Exists(filename)) { result = filename + " Not Found."; return(CHDManCheck.CHDNotFound); } string shortName = NameFix.GetShortPath(filename); using (Process exeProcess = new Process()) { exeProcess.StartInfo.FileName = chdPath; ReportError.LogOut("CHD: FileName :" + exeProcess.StartInfo.FileName); exeProcess.StartInfo.Arguments = "verify -i \"" + shortName + "\""; ReportError.LogOut("CHD: Arguments :" + exeProcess.StartInfo.Arguments); // Set UseShellExecute to false for redirection. exeProcess.StartInfo.UseShellExecute = false; // Stops the Command window from popping up. exeProcess.StartInfo.CreateNoWindow = true; // Redirect the standard output. // This stream is read asynchronously using an event handler. exeProcess.StartInfo.RedirectStandardOutput = true; exeProcess.StartInfo.RedirectStandardError = true; // Set our event handler to asynchronously read the process output. exeProcess.OutputDataReceived += CHDOutputHandler; exeProcess.ErrorDataReceived += CHDErrorHandler; _outputLineCount = 0; _errorLines = 0; ReportError.LogOut("CHD: Scanning Starting"); exeProcess.Start(); // Start the asynchronous read of the process output stream. exeProcess.BeginOutputReadLine(); exeProcess.BeginErrorReadLine(); // Wait for the process finish. exeProcess.WaitForExit(); ReportError.LogOut("CHD: Scanning Finished"); } result = _result; if (_resultType == CHDManCheck.Unset) { _resultType = CHDManCheck.Good; } _thWrk.Report(new bgwText3("")); ReportError.LogOut("CHD: returning result " + _resultType + " " + result); return(_resultType); }
/// <summary> /// Generates Files based on the current Configuration. /// Returns operation-result. /// </summary> public OperationResult <int> Merge(ThreadWorker <int> Worker) { General.ContractRequiresNotNull(Worker); var MergedObjects = 0; try { this.CurrentWorker = Worker; this.CurrentWorker.ReportProgress(0, "Starting."); // 1. Determine source objects... // 1.1. Determine source meta-definitions (declared in Domain) and their equivalents this.CurrentWorker.ReportProgress(10, "Determining Domain equivalents"); this.DetermineDomainEquivalents(); // 1.2. Determine source objects and their equivalents // (excluding Domain's meta-definitions, but including possible floating/orphan meta-definitions) var ProgressPercentageStart = 10.0; var ProgressPercentageEnd = 40.0; var ProgressStep = ((ProgressPercentageEnd - ProgressPercentageStart) / (double)SourceEntities.Count); var ProgressPercentage = ProgressPercentageStart; foreach (var Entity in SourceEntities) { this.CurrentWorker.ReportProgress((int)ProgressPercentage, "Reading object '" + Entity.ToStringAlways() + "'"); ProgressPercentage += ProgressStep; DetermineSourceChildren(Entity); } // this.MergeIdea(this.SourceComposition, 1.0, 99.0); // Get selected Ideas (first Concepts, then Relationships and the related Ideas by the later) // Recursively, get the selected composite Ideas ProgressPercentageStart = ProgressPercentageEnd; ProgressPercentageEnd = 66.6; ProgressStep = ((ProgressPercentageEnd - ProgressPercentageStart) / (double)SourceEntities.Count); ProgressPercentage = ProgressPercentageStart; foreach (var Entity in this.EquivalentEntities.Keys) { this.CurrentWorker.ReportProgress((int)ProgressPercentage, "Matching object '" + Entity.ToStringAlways() + "'"); ProgressPercentage += ProgressStep; DetermineEquivalent(Entity); } // 3. Determine Target equivalents, if any, to later reappoint references // 4. At Target Composition Domain, create clones of dominant meta-definitions + base-content // 5. At Target Composition container Ideas, create clones of source Ideas // Finish this.CurrentWorker.ReportProgress(100, "Merge complete."); this.CurrentWorker = null; } catch (Exception Problem) { this.CurrentWorker = null; return(OperationResult.Failure <int>("Cannot complete merge.\nProblem: " + Problem.Message, Result: MergedObjects)); } return(OperationResult.Success <int>(MergedObjects, "Merge executed")); }
public async void Start( double pollingInteval, Locales ffxivLocale = Locales.JA) { lock (this) { if (this.isStarted) { return; } this.isStarted = true; } this.FFXIVLocale = ffxivLocale; this.attachFFXIVPluginWorker = new System.Timers.Timer(); this.attachFFXIVPluginWorker.AutoReset = true; this.attachFFXIVPluginWorker.Interval = 5000; this.attachFFXIVPluginWorker.Elapsed += (s, e) => { try { this.Attach(); lock (ResourcesLock) { this.LoadSkillList(); this.LoadZoneList(); this.MergeSkillList(); } } catch (Exception ex) { AppLogger.Error(ex, "Attach FFXIV_ACT_Plugin error"); } }; this.scanFFXIVWorker = new ThreadWorker(() => { this.RefreshActive(); if (!this.IsAvailable) { Thread.Sleep(5000); #if !DEBUG return; #endif } this.RefreshCombatantList(); this.RefreshCurrentPartyIDList(); }, pollingInteval, nameof(this.attachFFXIVPluginWorker)); await Task.Run(() => { Thread.Sleep(CommonHelper.GetRandomTimeSpan()); this.attachFFXIVPluginWorker.Start(); Thread.Sleep(CommonHelper.GetRandomTimeSpan()); this.scanFFXIVWorker.Run(); // XIVDBをロードする Thread.Sleep(CommonHelper.GetRandomTimeSpan()); XIVDB.Instance.FFXIVLocale = ffxivLocale; XIVDB.Instance.Load(); // PC名記録をロードする Thread.Sleep(CommonHelper.GetRandomTimeSpan()); PCNameDictionary.Instance.Load(); // PTリストの並び順をロードする Thread.Sleep(CommonHelper.GetRandomTimeSpan()); PCOrder.Instance.Load(); }); }
private void handle_rss_watcher_newdata(int[] data) { foreach (int id in data) { if (this.Mode == BoardMode.None) { return; } if (!this.watched_threads.ContainsKey(id)) { if (!this._404_threads.Contains(id)) { ThreadWorker t = new ThreadWorker(this, id); t.BumpLimit = this.BumpLimit; t.ImageLimit = this.ImageLimit; t.AddedAutomatically = true; this.watched_threads.Add(id, t); t.Thread404 += this.handle_thread_404; t.Start(); Log(new LogEntry() { Level = LogEntry.LogLevel.Info, Message = string.Format("Found new thread {0}", id), Sender = "LightWatcher", Title = string.Format("/{0}/", this.Board) }); } } } }
private void handle_thread_404(ThreadWorker instance) { this.watched_threads.Remove(instance.ID); this._404_threads.Add(instance.ID); instance.Dispose(); instance.Thread404 -= this.handle_thread_404; Log(new LogEntry() { Level = LogEntry.LogLevel.Info, Message = string.Format("Thread '{0}' has 404'ed", instance.ID), Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); }
public override void Start() { ReadSettings(); Log.Info($"Starting HTTP Info Server on port {Port}"); worker = new ThreadWorker <RequestInfo>(); worker.QueueResponses = false; Server.OnUpdateEvent.Connect(() => { worker.Respond(info => { info.Request.Respond(); return(info.Request); }); }); var listener = new HttpListener(); Server.OnDestroyEvent.Connect(() => { listener.Abort(); }); listener.Prefixes.Add($"http://*:{Port}/"); if (PortHttps >= 0 && PortHttps != Port) { listener.Prefixes.Add($"https://*:{PortHttps}/"); } listener.Start(); listener.BeginGetContext(listenerCallback, listener); Log.Debug($"Started HTTP(S) Info Server on port {Port}"); DistanceServerMain.GetEvent <Events.ClientToAllClients.ChatMessage>().Connect((data, info) => { var playerMatch = Regex.Match(data.message_, @"^\[[0-9A-F]{6}\](.*?)\[FFFFFF\]: (.*)$"); if (!playerMatch.Success) { return; } var playerName = Regex.Replace(playerMatch.Groups[1].ToString(), @"\[.*\]", "").ToLower(); var player = Server.ValidPlayers.Find(distPlayer => distPlayer.Name.ToLower() == Regex.Replace(playerMatch.Groups[1].ToString(), @"\[.*\]", "").ToLower()); if (player == null) { return; } var message = playerMatch.Groups[2].ToString(); Match match; match = Regex.Match(message, @"^/unlink$"); if (match.Success) { var keysToRemove = new List <string>(); foreach (var pair in Links) { if (pair.Value == player.UnityPlayerGuid) { keysToRemove.Add(pair.Key); } } foreach (var key in keysToRemove) { Links.Remove(key); } Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", $"Your game session has been unlinked from {keysToRemove.Count} web session{(keysToRemove.Count == 1 ? "s" : "")}")); return; } match = Regex.Match(message, @"^/link (\w{6})$"); if (match.Success) { var code = match.Groups[1].ToString().ToUpper(); if (!CodesReverse.ContainsKey(code)) { var add = ""; if (HelpTextWebsite != null) { add = $"\nVisit {HelpTextWebsite.Replace("$linkcode", GetOrGenerateCode(player.UnityPlayerGuid))} to view and vote online."; } Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", "Invalid link code!" + add)); } Links[CodesReverse[code]] = player.UnityPlayerGuid; CodesReverse.Remove(code); Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", $"Your game session has been linked to a web session!\nType [00FFFF]/unlink[-] to undo this.")); return; } match = Regex.Match(message, @"^/link"); if (match.Success) { if (HelpTextWebsite != null) { Server.SayLocalChat(player.UnityPlayer, DistanceChat.Server("HttpServer:Link", $"Visit {HelpTextWebsite.Replace("$linkcode", GetOrGenerateCode(player.UnityPlayerGuid))} to view and vote online.")); } return; } }); Manager.Server.OnPlayerValidatedEvent.Connect(player => { GetOrGenerateCode(player.UnityPlayerGuid); }); var autoServer = Manager.GetPlugin <BasicAutoServer.BasicAutoServer>(); if (autoServer != null) { Log.Debug("Set LinkCodeGetter in BasicAutoServer"); autoServer.LinkCodeGetter = player => { return(GetOrGenerateCode(player.UnityPlayerGuid)); }; } Manager.Server.OnPlayerDisconnectedEvent.Connect(player => { Expiry[player.UnityPlayerGuid] = DistanceServerMain.UnixTime + 5 * 60; string keyToRemove = null; foreach (var pair in CodesForward) { if (pair.Value == player.UnityPlayerGuid) { keyToRemove = pair.Key; break; } } if (keyToRemove != null) { CodesForward.Remove(keyToRemove); } }); double lastUpdate = 0; Manager.Server.OnUpdateEvent.Connect(() => { var now = DistanceServerMain.UnixTime; if (now - lastUpdate >= 60) { lastUpdate = now; var KeysToRemove = new List <string>(); foreach (var pair in Links) { if (IsExpired(pair.Key, now) || IsExpired(pair.Value, now)) { KeysToRemove.Add(pair.Key); } } foreach (var key in KeysToRemove) { Links.Remove(key); } KeysToRemove.Clear(); foreach (var pair in CodesForward) { if (IsExpired(pair.Value, now)) { KeysToRemove.Add(pair.Key); } } foreach (var key in KeysToRemove) { CodesForward.Remove(key); } KeysToRemove.Clear(); foreach (var pair in CodesReverse) { if (IsExpired(pair.Value, now)) { KeysToRemove.Add(pair.Key); } } foreach (var key in KeysToRemove) { CodesReverse.Remove(key); } } }); Log.Debug($"Started handling code linking"); }
public void AddThreadId(int id, bool thumbOnly) { ThreadWorker t = null; if (this.watched_threads.ContainsKey(id)) { t = this.watched_threads[id]; } else { t = new ThreadWorker(this, id); t.ImageLimit = this.ImageLimit; t.BumpLimit = this.BumpLimit; this.watched_threads.Add(id, t); t.Thread404 += this.handle_thread_404; } t.AddedAutomatically = false; // THIS IS CRITICAL, OTHERWISE IT PREVENT MANUALLY ADDED THREADS FROM STARTING IN MONITOR MODE t.ThumbOnly = thumbOnly; t.Start(); SaveManuallyAddedThreads(); }
///////////////////////////////////////////////////////////// // Use: Ok Button clicked Handler // ///////////////////////////////////////////////////////////// private void bOk_Click(object sender, EventArgs e) { bool silentOp = _Application.SilentOperation; _Application.SilentOperation = true; PartDocument template = _Application.Documents.Open( _ThreadTemplatePath, false) as PartDocument; _Application.SilentOperation = silentOp; if (!ValidateTemplateParameters(template)) { DialogResult res = MessageBox.Show( "Missing sketch parameter in template file!", "Invalid Template", MessageBoxButtons.OK, MessageBoxIcon.Error); bOk.Enabled = false; _ThreadTemplatePath = string.Empty; tbTemplate.Text = string.Empty; if (template != _Application.ActiveDocument) { template.Close(true); } return; } List <ThreadFeature> threads = new List <ThreadFeature>(); foreach (System.Object selectedObj in _InteractionManager.SelectedEntities) { ThreadFeature thread = selectedObj as ThreadFeature; if (thread.Suppressed) { continue; } threads.Add(thread); } PlanarSketch templateSketch = template.ComponentDefinition.Sketches[1]; if (!ThreadWorker.ModelizeThreads( _Document, templateSketch, threads, _extraPitch)) { DialogResult res = MessageBox.Show( "Failed to create CoilFeature... " + "Try with a bigger Pitch Offset value", "Modelization Error", MessageBoxButtons.OKCancel, MessageBoxIcon.Error); switch (res) { case DialogResult.OK: //template.Close(true); return; default: break; } } // Problem: closing the template doc here // will empty the undo stack (as designed)... //template.Close(true); if (!_cleaned) { CleanUp(); } _InteractionManager.Terminate(); }
///////////////////////////////////////////////////////////// // Use: OnSelect ThreadFeature Handler. // ///////////////////////////////////////////////////////////// void SelectEvents_OnSelect( ObjectsEnumerator JustSelectedEntities, SelectionDeviceEnum SelectionDevice, Point ModelPosition, Point2d ViewPosition, Inventor.View View) { foreach (System.Object obj in JustSelectedEntities) { PartFeature feature = obj as PartFeature; ThreadFeature thread = obj as ThreadFeature; ThreadInfo threadInfo = thread.ThreadInfo; Face threadedFace = thread.ThreadedFace[1]; if (feature.Suppressed) { continue; } if (thread.ThreadInfoType == ThreadTypeEnum.kTaperedThread && threadedFace.SurfaceType != SurfaceTypeEnum.kConeSurface) { DialogResult res = MessageBox.Show( "Threaded face surface type is not cone surface but it is applied" + System.Environment.NewLine + "with tapered thread. ThreadModeler cannot modelize this thread.", "Invalid Surface Type", MessageBoxButtons.OK, MessageBoxIcon.Error); continue; } string iMateName = string.Empty; if (Toolkit.HasiMate(threadedFace, out iMateName)) { DialogResult res = MessageBox.Show( "Threaded face or one of its edge has" + " iMate associated to it." + System.Environment.NewLine + "Please delete iMate " + iMateName + " before modelizing this thread.", "Invalid iMate", MessageBoxButtons.OK, MessageBoxIcon.Error); continue; } double pitch = ThreadWorker.GetThreadPitch(threadInfo); string pitchStr = ThreadWorker.GetThreadPitchStr(threadInfo, (Document)_Document); string minStr = _Document.UnitsOfMeasure.GetStringFromValue( ThreadWorker.ThresholdPitchCm, UnitsTypeEnum.kDefaultDisplayLengthUnits); if (pitch < ThreadWorker.ThresholdPitchCm) { DialogResult res = MessageBox.Show( "Selected thread pitch " + "is too small (" + pitchStr + ")." + System.Environment.NewLine + "The minimum thread pitch that can " + "be modelized is " + minStr + " .", "Invalid Thread Pitch", MessageBoxButtons.OK, MessageBoxIcon.Error); continue; } ListViewItem item = lvFeatures.Items.Add(feature.Name); item.Tag = feature; item.SubItems.Add(pitchStr); item.SubItems.Add(ThreadWorker.GetThreadTypeStr( feature)); item.SubItems.Add( ThreadWorker.GetThreadedFaceTypeStr( threadedFace)); } _selecSetPopulated = (lvFeatures.Items.Count != 0); bOk.Enabled = ValidateOkButton(); }
private static void StartUpCode(ThreadWorker e) { RepairStatus.InitStatusCheck(); DB.Read(e); }
public static RvFile ReadInDatFile(RvDat datFile, ThreadWorker thWrk) { try { _thWrk = thWrk; string datRootFullName = datFile.GetData(RvDat.DatData.DatRootFullName); DatRead dr = new DatRead { ErrorReport = ReadError }; string fullPath = RvFile.GetDatPhysicalPath(datRootFullName); Debug.WriteLine("Reading Dat " + fullPath); dr.ReadDat(fullPath, out DatHeader dh); if (dh == null) { return(null); } string extraPath = !string.IsNullOrEmpty(dh.RootDir) ? dh.RootDir : dh.Name; string dirName = Path.GetDirectoryName(datRootFullName) + System.IO.Path.DirectorySeparatorChar + extraPath + System.IO.Path.DirectorySeparatorChar; DatRule datRule = FindDatRule(dirName); DatClean.CleanFilenames(dh.BaseDir); switch (datRule.Filter) { case FilterType.CHDsOnly: DatClean.RemoveNonCHD(dh.BaseDir); break; case FilterType.RomsOnly: DatClean.RemoveCHD(dh.BaseDir); break; } DatClean.RemoveNoDumps(dh.BaseDir); SetMergeType(datRule, dh); if (datRule.SingleArchive) { DatClean.MakeDatSingleLevel(dh); } DatClean.RemoveUnNeededDirectories(dh.BaseDir); SetCompressionMethod(datRule, dh); // This sorts the files into the required dir order for the set compression type. DatClean.DirectoryExpand(dh.BaseDir); // this works because we only expand files, so the order inside the zip / 7z does not matter. DatClean.RemoveEmptyDirectories(dh.BaseDir); DatClean.CleanFilenamesFixDupes(dh.BaseDir); // you may get repeat filenames inside Zip's / 7Z's and they may not be sorted to find them by now. RvFile newDir = ExternalDatConverter.ConvertFromExternalDat(dh, datRootFullName, datFile.TimeStamp); return(newDir); } catch (Exception e) { string datRootFullName = datFile?.GetData(RvDat.DatData.DatRootFullName); Console.WriteLine(e); throw new Exception("Error is DAT " + datRootFullName + " " + e.Message); } }
private void load_catalog() { while (true) { try { Log(new LogEntry() { Level = LogEntry.LogLevel.Info, Message = "Downloading catalog data...", Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); CatalogItem[][] catalog = Program.aw.GetCatalog(this.Board); Log(new LogEntry() { Level = LogEntry.LogLevel.Success, Message = "Catalog data downloaded", Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); int thread_count = 0; int started_count = 0; foreach (CatalogItem[] page in catalog) { foreach (CatalogItem thread in page) { thread_count++; if (Mode == BoardMode.None) { //board watcher have been stopped, return return; } ThreadWorker tw = null; if (!watched_threads.ContainsKey(thread.ID)) { tw = new ThreadWorker(this, thread.ID) { ImageLimit = thread.ImageLimit, BumpLimit = thread.BumpLimit, AddedAutomatically = true }; tw.Thread404 += this.handle_thread_404; watched_threads.Add(thread.ID, tw); } else { tw = watched_threads[thread.ID]; if (!tw.AddedAutomatically) { continue; } } if (this.Mode == BoardMode.Monitor) { if (!this.MatchFilters(thread)) { //in monitor mode, don't auto-start unacceptable threads this.Log(new LogEntry() { Level = LogEntry.LogLevel.Info, Message = "Thread " + thread.ID.ToString() + " has no matching filter, skipping it.", Sender = "BoardWatcher", Title = "" }); } else { started_count++; Log(new LogEntry() { Level = LogEntry.LogLevel.Info, Message = string.Format("Thread {0} has matching filters, starting it.", thread.ID), Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); tw.Start(); } } else if (this.Mode == BoardMode.FullBoard || this.Mode == BoardMode.Harvester) { if (Program.verbose) { Log(new LogEntry() { Level = LogEntry.LogLevel.Info, Message = string.Format("Starting thread worker for thread # {0}", thread.ID), Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); } started_count++; Task.Factory.StartNew((Action)delegate { //Allow 5 sec delay between thread startup System.Threading.Thread.Sleep(5000); tw.Start(); }); } } } Log(new LogEntry() { Level = LogEntry.LogLevel.Success, Message = string.Format("Finished loading {0} thread, {1} started.", thread_count, started_count), Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); //breaks the while break; } catch (Exception ex) { if (ex.Message.Contains("404")) { //board does not exist! board_404 = true; return; } Log(new LogEntry() { Level = LogEntry.LogLevel.Fail, Message = string.Format("Could not load catalog data '{0}' @ '{1}', retrying in 5 seconds", ex.Message, ex.StackTrace), Sender = "BoardWatcher", Title = string.Format("/{0}/", this.Board) }); System.Threading.Thread.Sleep(5000); } } }
public static void QueueTask(int LinePriority,Task task,Task post) { if (taskPoolObject == null) { taskPoolObject = new GameObject("_taskPoolObject"); taskPoolObject.AddComponent<TaskPool>(); JobQueue = new List<Job>(); postJobQueue = new List<Job>(); rwLock = new ReaderWriterLockSlim(); tasks = new List<Task>(); if (workers == null) { workers = new ThreadWorker[8]; for (int i = 0; i < 8; i++) { workers[i] = new ThreadWorker(i); workers[i].workerThread = new Thread(new ThreadStart(workers[i].Work)); workers[i].workerThread.Start(); } //Debug.Log("started "+workers.Count.ToString()+" Workers"); } } Job InsertJob = new Job(task,post,LinePriority); rwLock.EnterUpgradeableReadLock(); try { if (JobQueue == null) { rwLock.EnterWriteLock(); try { JobQueue = new List<Job>(); } finally { rwLock.ExitWriteLock(); } } if (JobQueue != null) { rwLock.EnterWriteLock(); try { JobQueue.Add(InsertJob); } finally { rwLock.ExitWriteLock(); } } } finally { rwLock.ExitUpgradeableReadLock(); } }
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(); } } } }
public MyThread(Thread t, ThreadWorker worker) { this.t = t; this.worker = worker; }
public static RvFile FromADir(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort) { string fullDir = dbDir.FullName; DatStatus datStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; RvFile fileDir = new RvFile(FileType.Dir); DirectoryInfo oDir = new DirectoryInfo(fullDir); DirectoryInfo[] oDirs = oDir.GetDirectories(); FileInfo[] oFiles = oDir.GetFiles(); // add all the subdirectories into scanDir foreach (DirectoryInfo dir in oDirs) { RvFile tDir = new RvFile(FileType.Dir) { Name = dir.Name, FileModTimeStamp = dir.LastWriteTime }; tDir.SetStatus(datStatus, GotStatus.Got); fileDir.ChildAdd(tDir); } // add all the files into scanDir foreach (FileInfo oFile in oFiles) { string fName = oFile.Name; if (fName == "__RomVault.tmp") { File.Delete(oFile.FullName); continue; } string fExt = Path.GetExtension(oFile.Name); FileType ft = DBTypeGet.fromExtention(fExt); if (Settings.rvSettings.FilesOnly) { ft = FileType.File; } RvFile tFile = new RvFile(ft) { Name = oFile.Name, Size = (ulong)oFile.Length, FileModTimeStamp = oFile.LastWriteTime }; tFile.FileStatusSet(FileStatus.SizeVerified); tFile.SetStatus(datStatus, GotStatus.Got); if (eScanLevel == EScanLevel.Level3 && tFile.FileType == FileType.File) { FromAFile(tFile, fullDir, eScanLevel, bgw, ref fileErrorAbort); } fileDir.ChildAdd(tFile); /* * // if we find a zip file add it as zip files. * // else * if (ft == FileType.File) * { * // Scanning a file * // * // Level1 & 2 : (are the same for files) Fully checksum changed only files * // Here we are just getting the TimeStamp of the File, and later * // if the TimeStamp was not matched we will have to read the files CRC, MD5 & SHA1 * // * // Level3: Fully checksum everything * // Get everything about the file right here so * // read CRC, MD5 & SHA1 * * errorCode = CHD.CheckFile(oFile, out tFile.AltSHA1, out tFile.AltMD5, out tFile.CHDVersion); * * if (errorCode == 0) * { * if (tFile.AltSHA1 != null) * { * tFile.FileStatusSet(FileStatus.AltSHA1FromHeader); * } * if (tFile.AltMD5 != null) * { * tFile.FileStatusSet(FileStatus.AltMD5FromHeader); * } * * // if we are scanning at Level3 then we get all the info here * if (EScanLevel == EScanLevel.Level3) * { * FileResults(fullDir, tFile); * ChdManCheck(fullDir, tFile); * } * } * else if (errorCode == 32) * { * tFile.GotStatus = GotStatus.FileLocked; * _bgw.Report(new bgwShowError(fullDir, "File Locked")); * } * else * { * string filename = Path.Combine(fullDir, tFile.Name); * ReportError.Show("File: " + filename + " Error: " + new Win32Exception(errorCode).Message + ". Scan Aborted."); * _fileErrorAbort = true; * return fileDir; * } * } */ } return(fileDir); }
// This is the actual method called in the Thread protected virtual void WorkerMethodWrapper () { int sleepTime = 0; autoReference = this; bool wasWokenUp = false; // Main loop while (started == 1) { bool result = false; result = WorkerMethod (); if (!result && wasWokenUp) waitHandle.Reset (); wasWokenUp = false; Thread.Yield (); if (result) { deepSleepTime = 8; sleepTime = 0; continue; } // If we are spinning too much, have a deeper sleep if (++sleepTime > sleepThreshold && sharedWorkQueue.Count == 0) { wasWokenUp = waitHandle.WaitOne ((deepSleepTime = deepSleepTime >= 0x4000 ? 0x4000 : deepSleepTime << 1)); } } started = 0; }
public static extern int piThreadCreate(ThreadWorker method);
public virtual bool Equals (ThreadWorker other) { return (other == null) ? false : object.ReferenceEquals (this.dDeque, other.dDeque); }
public static bool Phase2Test(RvFile dbFile, RvFile testFile, EScanLevel eScanLevel, string fullDir, ThreadWorker thWrk, ref bool fileErrorAbort, out bool MatchedAlt) { MatchedAlt = false; //Debug.WriteLine("Comparing Dat File " + dbFile.TreeFullName); //Debug.WriteLine("Comparing File " + testFile.TreeFullName); int retv = DBHelper.CompareName(dbFile, testFile); if (retv != 0) { return(false); } FileType dbfileType = dbFile.FileType; FileType dbtestFile = testFile.FileType; if (dbfileType != FileType.File || dbtestFile != FileType.File) { return(false); } Populate.FromAFile(testFile, fullDir, eScanLevel, thWrk, ref fileErrorAbort); if (fileErrorAbort) { return(false); } if (testFile.GotStatus == GotStatus.FileLocked) { return(false); } return(CompareWithAlt(dbFile, testFile, out MatchedAlt)); }
public static void ScanFiles(ThreadWorker e) { #if !DEBUG try { #endif _fileErrorAbort = false; _cacheSaveTimer = new Stopwatch(); _cacheSaveTimer.Reset(); if (Settings.rvSettings.CacheSaveTimerEnabled) { _cacheSaveTimer.Start(); } _thWrk = e; if (_thWrk == null) { return; } _thWrk.Report(new bgwText("Clearing DB Status")); RepairStatus.ReportStatusReset(DB.DirRoot); _thWrk.Report(new bgwText("Finding Dir's to Scan")); //Next get a list of all the directories to be scanned List <RvFile> lstDir = new List <RvFile>(); DBHelper.GetSelectedDirListStart(ref lstDir, StartAt); _thWrk.Report(new bgwText("Scanning Dir's")); _thWrk.Report(new bgwSetRange(lstDir.Count)); //Scan the list of directories. for (int i = 0; i < lstDir.Count; i++) { _thWrk.Report(i + 1); _thWrk.Report(new bgwText("Scanning Dir : " + lstDir[i].FullName)); string lDir = lstDir[i].FullName; Console.WriteLine(lDir); if (Directory.Exists(lDir)) { lstDir[i].GotStatus = GotStatus.Got; CheckADir(lstDir[i], true); } else { MarkAsMissing(lstDir[i]); } if (_thWrk.CancellationPending || _fileErrorAbort) { break; } } _thWrk.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk.Report(new bgwText("File Scan Complete")); _thWrk.Finished = true; _thWrk = null; #if !DEBUG } catch (Exception exc) { ReportError.UnhandledExceptionHandler(exc); _thWrk?.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk?.Report(new bgwText("Complete")); if (_thWrk != null) { _thWrk.Finished = true; } _thWrk = null; } #endif }
public static void UpdateDat(ThreadWorker thWrk) { try { _thWrk = thWrk; if (_thWrk == null) { return; } _thWrk.Report(new bgwText("Clearing DB Status")); RepairStatus.ReportStatusReset(DB.DirTree); _datCount = 0; _thWrk.Report(new bgwText("Finding Dats")); RvFile datRoot = new RvFile(FileType.Dir) { Name = "RomVault", DatStatus = DatStatus.InDatCollect }; // build a datRoot tree of the DAT's in DatRoot, and count how many dats are found if (!RecursiveDatTree(datRoot, out _datCount)) { _thWrk.Report(new bgwText("Dat Update Complete")); _thWrk.Finished = true; _thWrk = null; return; } _thWrk.Report(new bgwText("Scanning Dats")); _datsProcessed = 0; // now compare the database DAT's with datRoot removing any old DAT's RemoveOldDats(DB.DirTree.Child(0), datRoot); // next clean up the File status removing any old DAT's RemoveOldDatsCleanUpFiles(DB.DirTree.Child(0)); _thWrk.Report(new bgwSetRange(_datCount - 1)); // next add in new DAT and update the files UpdateDatList(DB.DirTree.Child(0), datRoot); // finally remove any unneeded directories from the TreeView RemoveOldTree(DB.DirTree.Child(0)); _thWrk.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk.Report(new bgwText("Dat Update Complete")); _thWrk.Finished = true; _thWrk = null; } catch (Exception exc) { ReportError.UnhandledExceptionHandler(exc); _thWrk?.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk?.Report(new bgwText("Complete")); if (_thWrk != null) { _thWrk.Finished = true; } _thWrk = null; } }
private void installInputHandler() { Debug.Assert(Deleting == false); Debug.Assert(socket != null); ThreadWorker tw = new ThreadWorker(this); Thread t = new Thread(new ThreadStart(tw.watchForActivity)); t.Priority = ThreadPriority.BelowNormal; t.IsBackground = true; t.Name = "WatchActivity"; t.Start(); }
public static void FromAFile(RvFile file, string directory, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort) { _bgw = bgw; string filename = Path.Combine(directory, string.IsNullOrWhiteSpace(file.FileName) ? file.Name : file.FileName); ICompress fileToScan = new Compress.File.File(); ZipReturn zr = fileToScan.ZipFileOpen(filename, file.FileModTimeStamp); if (zr == ZipReturn.ZipFileLocked) { file.GotStatus = GotStatus.FileLocked; return; } if (zr != ZipReturn.ZipGood) { ReportError.Show("File: " + filename + " Error: " + zr + ". Scan Aborted."); file.GotStatus = GotStatus.FileLocked; fileErrorAbort = true; return; } if (_fs == null) { _fs = new FileScan(); } List <FileScan.FileResults> fr = _fs.Scan(fileToScan, true, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3); file.HeaderFileType = fr[0].HeaderFileType; file.Size = fr[0].Size; file.CRC = fr[0].CRC; file.SHA1 = fr[0].SHA1; file.MD5 = fr[0].MD5; file.AltSize = fr[0].AltSize; file.AltCRC = fr[0].AltCRC; file.AltSHA1 = fr[0].AltSHA1; file.AltMD5 = fr[0].AltMD5; file.FileStatusSet( FileStatus.SizeVerified | (file.HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) | (file.CRC != null ? FileStatus.CRCVerified : 0) | (file.SHA1 != null ? FileStatus.SHA1Verified : 0) | (file.MD5 != null ? FileStatus.MD5Verified : 0) | (file.AltSize != null ? FileStatus.AltSizeVerified : 0) | (file.AltCRC != null ? FileStatus.AltCRCVerified : 0) | (file.AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) | (file.AltMD5 != null ? FileStatus.AltMD5Verified : 0) ); if (fr[0].HeaderFileType == HeaderFileType.CHD) { bool deepCheck = (eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3); CHD.fileProcess = FileProcess; CHD.fileProgress = FileProgress; CHD.fileSystemError = FileSystemError; CHD.fileError = FileError; CHD.generalError = GeneralError; hdErr result = CHD.CheckFile(file.Name, directory, Settings.isLinux, ref deepCheck, out uint?chdVersion, out byte[] chdSHA1, out byte[] chdMD5, ref fileErrorAbort); switch (result) { case hdErr.HDERR_NONE: file.CHDVersion = chdVersion; if (chdSHA1 != null) { file.AltSHA1 = chdSHA1; file.FileStatusSet(FileStatus.AltSHA1FromHeader); if (deepCheck) { file.FileStatusSet(FileStatus.AltSHA1Verified); } } if (chdMD5 != null) { file.AltMD5 = chdMD5; file.FileStatusSet(FileStatus.AltMD5FromHeader); if (deepCheck) { file.FileStatusSet(FileStatus.AltMD5Verified); } } break; case hdErr.HDERR_OUT_OF_MEMORY: case hdErr.HDERR_INVALID_FILE: case hdErr.HDERR_INVALID_DATA: case hdErr.HDERR_READ_ERROR: case hdErr.HDERR_DECOMPRESSION_ERROR: case hdErr.HDERR_CANT_VERIFY: file.GotStatus = GotStatus.Corrupt; break; default: ReportError.UnhandledExceptionHandler(result.ToString()); break; } } fileToScan.ZipFileClose(); }
public void Dispose_WaitsForTaskToComplete_WhenItTakesLessThanDefinedTimeout(string workerName) { // arrange var transport = A.Fake<ITransport>(); var pipeline = A.Fake<IPipeline>(); var pipelineInvoker = A.Fake<IPipelineInvoker>(); var context = A.Fake<ThreadWorkerSynchronizationContext>(); var manager = A.Fake<ParallelOperationsManager>(fake => fake.WithArgumentsForConstructor(() => new ParallelOperationsManager(1))); var backOff = A.Fake<IBackoffStrategy>(); var logFactory = A.Fake<IRebusLoggerFactory>(); var log = A.Fake<ILog>(); var timeout = TimeSpan.FromSeconds(10); A.CallTo(() => logFactory.GetCurrentClassLogger()) .Returns(log); // have stuff to do A.CallTo(() => manager.HasPendingTasks) .Returns(true); var taskTakingTime = TimeSpan.FromSeconds(5); // wait a bit, then simulate task completion. Task.Run(async () => { await Task.Delay(taskTakingTime) .ConfigureAwait(true); // forcing sync context for the same thread A.CallTo(() => manager.HasPendingTasks) .Returns(false); }); // system under test var sut = new ThreadWorker(transport, pipeline, pipelineInvoker, workerName, context, manager, backOff, logFactory, timeout); // act var timer = Stopwatch.StartNew(); sut.Dispose(); timer.Stop(); // assert timer.Elapsed .Should().BeCloseTo(taskTakingTime, 1000); // NO logs. A.CallTo(() => log.Warn("Not all async tasks were able to finish within given timeout of {0} seconds!", timeout.TotalSeconds)) .MustNotHaveHappened(); A.CallTo(() => log.Warn("Worker {0} did not stop withing {1} seconds timeout!", workerName, timeout.TotalSeconds)) .MustNotHaveHappened(); }
public virtual bool Equals(ThreadWorker other) { return((other == null) ? false : object.ReferenceEquals(this.dDeque, other.dDeque)); }
public static void FromAFile(RvFile file, string directory, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort) { string filename = Path.Combine(directory, file.Name); ICompress fileToScan = new Compress.File.File(); ZipReturn zr = fileToScan.ZipFileOpen(filename, file.FileModTimeStamp); if (zr == ZipReturn.ZipFileLocked) { file.GotStatus = GotStatus.FileLocked; return; } if (zr != ZipReturn.ZipGood) { ReportError.Show("File: " + filename + " Error: " + zr + ". Scan Aborted."); file.GotStatus = GotStatus.FileLocked; fileErrorAbort = true; return; } if (_fs == null) { _fs = new FileScan(); } List <FileScan.FileResults> fr = _fs.Scan(fileToScan, true, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3); file.HeaderFileType = fr[0].HeaderFileType; file.Size = fr[0].Size; file.CRC = fr[0].CRC; file.SHA1 = fr[0].SHA1; file.MD5 = fr[0].MD5; file.AltSize = fr[0].AltSize; file.AltCRC = fr[0].AltCRC; file.AltSHA1 = fr[0].AltSHA1; file.AltMD5 = fr[0].AltMD5; file.FileStatusSet( FileStatus.SizeVerified | (file.HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) | (file.CRC != null ? FileStatus.CRCVerified : 0) | (file.SHA1 != null ? FileStatus.SHA1Verified : 0) | (file.MD5 != null ? FileStatus.MD5Verified : 0) | (file.AltSize != null ? FileStatus.AltSizeVerified : 0) | (file.AltCRC != null ? FileStatus.AltCRCVerified : 0) | (file.AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) | (file.AltMD5 != null ? FileStatus.AltMD5Verified : 0) ); if (fr[0].HeaderFileType == HeaderFileType.CHD) { CHD.CheckFile(file, directory); if (eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3) { Utils.ChdManCheck(file, directory, bgw, ref fileErrorAbort); } } fileToScan.ZipFileClose(); }
/// <summary> /// Generates a Report based on the current Configuration. /// Returns operation-result. /// </summary> // IMPORTANT: See this page about the VisualsToXpsDocument class: // http://msdn.microsoft.com/en-us/library/system.windows.xps.visualstoxpsdocument.aspx public OperationResult <int> Generate(ThreadWorker <int> Worker) { General.ContractRequiresNotNull(Worker); try { this.Configuration = this.OriginalConfiguration.GenerateDeepClone(); // Cloned to allow inter-thread use. var Result = new FixedDocument(); IsAtGenerationStart = true; this.CurrentWorker = Worker; this.CurrentWorker.ReportProgress(0, "Starting."); // IMPORTANT: This page must be created to determine initial dimensions, // even when the user selected to exclude it from the document. var TitlePage = this.CreateTitlePage(this.Configuration.DocSection_TitlePage); if (this.Configuration.DocSection_TitlePage) { Result.Pages.Add(this.CreatePageContainer(TitlePage)); } this.CurrentWorker.ReportProgress(1, "Generating Composition content."); // IMPORTANT: This ReportPagesMaker creation must be after the first page to get the page's dimensions. var PagesMaker = new ReportStandardPagesMaker(this); /* PENDING * if (this.Configuration.DocSection_TableOfContents) * this.CreateTableOfContents().ForEach(page => Result.Pages.Add(this.CreatePageContainer(page))); */ if (this.Configuration.DocSection_Composition) { this.CreateCompositeContent(PagesMaker, this.SourceComposition, 0.0, 1.0, 90.0); } this.CurrentWorker.ReportProgress(90, "Generating Domain content."); if (this.Configuration.DocSection_Domain) { this.CreateDomainContent(PagesMaker, this.SourceComposition.CompositeContentDomain); } this.CurrentWorker.ReportProgress(93, "Paginating."); var Pages = PagesMaker.GetPages(); foreach (var Page in Pages) { Result.Pages.Add(this.CreatePageContainer(Page)); } this.CurrentWorker.ReportProgress(97, "Saving to temporal XPS document."); var FileName = General.GenerateRandomFileName(this.SourceComposition.TechName + "_TMP", "xps"); this.GeneratedDocumentTempFilePath = Path.Combine(AppExec.ApplicationUserTemporalDirectory, FileName); Display.SaveDocumentAsXPS(Result, this.GeneratedDocumentTempFilePath); this.CurrentWorker.ReportProgress(100, "Generation complete."); this.CurrentWorker = null; } catch (Exception Problem) { this.CurrentWorker = null; return(OperationResult.Failure <int>("Cannot execute generation.\nProblem: " + Problem.Message)); } return(OperationResult.Success <int>(0, "Generation complete.")); }
public static void ScanFiles(ThreadWorker thWrk) { try { _thWrk = thWrk; if (_thWrk == null) { return; } _progressCounter = 0; Stopwatch sw = new Stopwatch(); sw.Reset(); sw.Start(); _thWrk.Report(new bgwSetRange(12)); _thWrk.Report(new bgwText("Clearing DB Status")); _thWrk.Report(_progressCounter++); RepairStatus.ReportStatusReset(DB.DirTree); ResetFileGroups(DB.DirTree); _thWrk.Report(new bgwText("Getting Selected Files")); _thWrk.Report(_progressCounter++); Debug.WriteLine("Start " + sw.ElapsedMilliseconds); List <RvFile> filesGot = new List <RvFile>(); List <RvFile> filesMissing = new List <RvFile>(); GetSelectedFiles(DB.DirTree, true, filesGot, filesMissing); Debug.WriteLine("GetSelected " + sw.ElapsedMilliseconds); _thWrk.Report(new bgwText("Sorting on CRC")); _thWrk.Report(_progressCounter++); RvFile[] filesGotSortedCRC = FindFixesSort.SortCRC(filesGot); Debug.WriteLine("SortCRC " + sw.ElapsedMilliseconds); // take the fileGot list and fileGroups list // this groups all the got files using there CRC _thWrk.Report(new bgwText("Index creation on got CRC")); _thWrk.Report(_progressCounter++); MergeGotFiles(filesGotSortedCRC, out FileGroup[] fileGroupsCRCSorted); Debug.WriteLine("Merge " + sw.ElapsedMilliseconds); _thWrk.Report(new bgwText("Index creation on got SHA1")); _thWrk.Report(_progressCounter++); FindFixesSort.SortFamily(fileGroupsCRCSorted, FindSHA1, FamilySortSHA1, out FileGroup[] fileGroupsSHA1Sorted); _thWrk.Report(new bgwText("Index creation on got MD5")); _thWrk.Report(_progressCounter++); FindFixesSort.SortFamily(fileGroupsCRCSorted, FindMD5, FamilySortMD5, out FileGroup[] fileGroupsMD5Sorted); // next make another sorted list of got files on the AltCRC // these are the same FileGroup classes as in the fileGroupsCRCSorted List, just sorted by AltCRC // if the files does not have an altCRC then it is not added to this list. _thWrk.Report(new bgwText("Index creation on got AltCRC")); _thWrk.Report(_progressCounter++); FindFixesSort.SortFamily(fileGroupsCRCSorted, FindAltCRC, FamilySortAltCRC, out FileGroup[] fileGroupsAltCRCSorted); _thWrk.Report(new bgwText("Index creation on got AltSHA1")); _thWrk.Report(_progressCounter++); FindFixesSort.SortFamily(fileGroupsCRCSorted, FindAltSHA1, FamilySortAltSHA1, out FileGroup[] fileGroupsAltSHA1Sorted); _thWrk.Report(new bgwText("Index creation on got AltMD5")); _thWrk.Report(_progressCounter++); FindFixesSort.SortFamily(fileGroupsCRCSorted, FindAltMD5, FamilySortAltMD5, out FileGroup[] fileGroupsAltMD5Sorted); _thWrk.Report(new bgwText("Merging in missing file list")); _thWrk.Report(_progressCounter++); // try and merge the missing File list into the FileGroup classes // using the altCRC sorted list and then the CRCSorted list MergeInMissingFiles(fileGroupsCRCSorted, fileGroupsSHA1Sorted, fileGroupsMD5Sorted, fileGroupsAltCRCSorted, fileGroupsAltSHA1Sorted, fileGroupsAltMD5Sorted, filesMissing); int totalAfterMerge = fileGroupsCRCSorted.Length; _thWrk.Report(new bgwText("Finding Fixes")); _thWrk.Report(_progressCounter++); FindFixesListCheck.GroupListCheck(fileGroupsCRCSorted); _thWrk.Report(new bgwText("Complete (Unique Files " + totalAfterMerge + ")")); _thWrk.Finished = true; _thWrk = null; } catch (Exception exc) { ReportError.UnhandledExceptionHandler(exc); _thWrk?.Report(new bgwText("Updating Cache")); DB.Write(); _thWrk?.Report(new bgwText("Complete")); if (_thWrk != null) { _thWrk.Finished = true; } _thWrk = null; } }
public static RvFile ReadInDatFile(RvDat datFile, ThreadWorker thWrk, out string extraDirName) { try { _thWrk = thWrk; extraDirName = null; string datRootFullName = datFile.GetData(RvDat.DatData.DatRootFullName); string fullPath = RvFile.GetDatPhysicalPath(datRootFullName); Debug.WriteLine("Reading Dat " + fullPath); DatRead.ReadDat(fullPath, ReadError, out DatHeader dh); if (dh == null) { return(null); } string dirNameRule = Path.GetDirectoryName(datRootFullName) + Path.DirSeparatorChar; if ( !datFile.MultiDatOverride && dh.Dir != "noautodir" && (datFile.MultiDatsInDirectory || !string.IsNullOrEmpty(dh.RootDir)) ) { // if we are auto adding extra directories then create a new directory. extraDirName = ""; if (string.IsNullOrEmpty(extraDirName) && datFile.UseDescriptionAsDirName && !string.IsNullOrWhiteSpace(dh.Description)) { extraDirName = dh.Description; } if (string.IsNullOrEmpty(extraDirName)) { extraDirName = dh.RootDir; } if (string.IsNullOrEmpty(extraDirName)) { extraDirName = dh.Name; } if (string.IsNullOrEmpty(extraDirName)) { extraDirName = Path.GetFileNameWithoutExtension(fullPath); } dirNameRule += VarFix.CleanFileName(extraDirName) + Path.DirSeparatorChar; } ReportError.LogOut($"DatRule {dirNameRule}"); DatRule datRule = FindDatRule(dirNameRule); DatClean.CleanFilenames(dh.BaseDir); switch (datRule.Filter) { case FilterType.CHDsOnly: DatClean.RemoveNonCHD(dh.BaseDir); break; case FilterType.RomsOnly: DatClean.RemoveCHD(dh.BaseDir); break; } DatClean.RemoveNoDumps(dh.BaseDir); SetMergeType(datRule, dh); if (datRule.SingleArchive) { DatClean.MakeDatSingleLevel(dh, datRule.UseDescriptionAsDirName, datRule.SubDirType, isFile(datRule, dh)); } DatClean.RemoveUnNeededDirectories(dh.BaseDir); SetCompressionMethod(datRule, dh); // This sorts the files into the required dir order for the set compression type. (And also sets '\' characters to '/' in zip files.) DatClean.DirectoryExpand(dh.BaseDir); // this works because we only expand files, so the order inside the zip / 7z does not matter. DatClean.RemoveEmptyDirectories(dh.BaseDir); DatClean.CleanFilenamesFixDupes(dh.BaseDir); // you may get repeat filenames inside Zip's / 7Z's and they may not be sorted to find them by now. RvFile newDir = ExternalDatConverter.ConvertFromExternalDat(dh, datFile); return(newDir); } catch (Exception e) { string datRootFullName = datFile?.GetData(RvDat.DatData.DatRootFullName); Console.WriteLine(e); throw new Exception("Error is DAT " + datRootFullName + " " + e.Message); } }
private string GetWatchedThreadsTableHtml() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < Program.active_dumpers.Count; i++) { try { BoardWatcher bw = Program.active_dumpers.ElementAt(i).Value; for (int index = 0; index < bw.watched_threads.Count; index++) { try { ThreadWorker tw = bw.watched_threads.ElementAt(index).Value; // Don't pollute the list with unactive thread workers (because no filter match) in monitor modes if (tw.AddedAutomatically && (!tw.IsActive) && (bw.Mode == BoardWatcher.BoardMode.Whitelist || bw.Mode == BoardWatcher.BoardMode.Blacklist)) { continue; } sb.Append("<tr>"); sb.AppendFormat("<td><a class=\"btn btn-default\" href='/action/removethreadworker/?board={0}&id={1}' title='Remove'><i class=\"fa fa-trash-o\"></i></a></td>", tw.Board.Board, tw.ID); if (tw.IsStatic) { sb.Append("<td><a class=\"btn btn-primary\" href='#'>Static</a></td>"); } else { if (tw.IsActive) { sb.AppendFormat("<td><a class=\"btn btn-warning\" href=\"/cancel/tw/{0}/{1}\">Stop</a></td>", bw.Board, tw.ID); } else { sb.AppendFormat("<td><a class=\"btn btn-info\" href=\"/cancel/twr/{0}/{1}\">Start</a></td>", bw.Board, tw.ID); } } sb.AppendFormat("<td>{0}</td>", string.Format("/{0}/", bw.Board)); sb.AppendFormat("<td>{0}</td>", tw.ID); sb.AppendFormat("<td>{0}</td>", tw.AddedAutomatically ? "<span class=\"label label-primary\">Yes</span>" : "<span class=\"label label-default\">No</span>"); sb.AppendFormat("<td>{0}</td>", tw.ThumbOnly ? "<span class=\"label label-primary\">Yes</span>" : "<span class=\"label label-default\">No</span>"); sb.AppendFormat("<td><a href='/boards/{0}/{1}' class='label label-danger'>*click*</a></td>", bw.Board, tw.ID); sb.AppendFormat("<td><pre>{0}</pre></td>", tw.ThreadTitle); sb.AppendFormat("<td>{0} ago</td>", HMSFormatter.GetReadableTimespan(DateTime.Now - tw.LastUpdated).ToLower()); sb.AppendFormat("<td>{0}</td>", tw.AutoSage ? "<span class=\"label label-primary\">Yes</span>" : "<span class=\"label label-default\">No</span>"); sb.AppendFormat("<td>{0}</td>", tw.ImageLimitReached ? "<span class=\"label label-primary\">Yes</span>" : "<span class=\"label label-default\">No</span>"); sb.AppendFormat("<td> <a href='/threadinfo?board={0}&id={1}' class='label label-primary'>Info</a> </td>", bw.Board, tw.ID); sb.Append("</tr>"); } catch (Exception) { if (index >= bw.watched_threads.Count) { break; } } } } catch (Exception) { if (i >= Program.active_dumpers.Count) { break; } } } return(sb.ToString()); }
void IThreadPoolHelper <T> .QueueMultipleUserWorkItemsAndWaitForCompletion(int maximumThreads, TimeSpan timeout, ThreadWorker <T> callback, List <T> parameters) { QueueMultipleUserWorkItemsAndWaitForCompletion(maximumThreads, timeout, callback, parameters); }
public static RvFile FromADir(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker bgw, ref bool fileErrorAbort) { string fullDir = dbDir.FullName; DatStatus datStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; RvFile fileDir = new RvFile(FileType.Dir); DirectoryInfo oDir = new DirectoryInfo(fullDir); DirectoryInfo[] oDirs = oDir.GetDirectories(); FileInfo[] oFiles = oDir.GetFiles(); // add all the subdirectories into scanDir foreach (DirectoryInfo dir in oDirs) { RvFile tDir = new RvFile(FileType.Dir) { Name = dir.Name, FileModTimeStamp = dir.LastWriteTime }; tDir.SetStatus(datStatus, GotStatus.Got); fileDir.ChildAdd(tDir); } // add all the files into scanDir foreach (FileInfo oFile in oFiles) { string fName = oFile.Name; if (fName == "__RomVault.tmp") { File.Delete(oFile.FullName); continue; } string fExt = Path.GetExtension(oFile.Name); FileType ft = DBTypeGet.fromExtention(fExt); if (Settings.rvSettings.FilesOnly) { ft = FileType.File; } RvFile tFile = new RvFile(ft) { Name = oFile.Name, Size = (ulong)oFile.Length, FileModTimeStamp = oFile.LastWriteTime }; tFile.FileStatusSet(FileStatus.SizeVerified); tFile.SetStatus(datStatus, GotStatus.Got); if (eScanLevel == EScanLevel.Level3 && tFile.FileType == FileType.File) { FromAFile(tFile, fullDir, eScanLevel, bgw, ref fileErrorAbort); } fileDir.ChildAdd(tFile); } return(fileDir); }
protected virtual void QueueMultipleUserWorkItemsAndWaitForCompletion(int maximumThreads, TimeSpan timeout, ThreadWorker <T> callback, List <T> parameters) { if (maximumThreads < 1) { maximumThreads = 1; } var pendingWorkItemsQueue = new Queue <CallbackState>(); var callbackStates = new List <CallbackState>(); var allWorkItemsCompletedEvent = new ManualResetEvent(false); var cancelWorkItemProcessing = new ManualResetEvent(false); // prepare all work items first... foreach (var parameter in parameters) { var callbackState = new CallbackState(callback, parameter, pendingWorkItemsQueue, allWorkItemsCompletedEvent, cancelWorkItemProcessing); pendingWorkItemsQueue.Enqueue(callbackState); callbackStates.Add(callbackState); } // ...and then start the first batch going for (var item = 0; item < Math.Min(maximumThreads, callbackStates.Count); item++) { QueueNextWorkItem(pendingWorkItemsQueue); } // done preparing and starting off the work DecrementThreadsWaitngToComplete(allWorkItemsCompletedEvent); // wait for everything to be completed if (!allWorkItemsCompletedEvent.WaitOne(timeout)) { cancelWorkItemProcessing.Set(); ReportWorkItemTimeouts(timeout, pendingWorkItemsQueue, callbackStates); } var callbacksWithExceptions = callbackStates.Where(cs => cs.CallbackException != null).ToList(); if (callbacksWithExceptions.Count > 0) { ReportWorkItemsWithExceptions(callbackStates, callbacksWithExceptions); } }
public static RvFile FromAZipFile(RvFile dbDir, EScanLevel eScanLevel, ThreadWorker thWrk) { RvFile fileDir = new RvFile(dbDir.FileType); DatStatus chechingDatStatus = dbDir.IsInToSort ? DatStatus.InToSort : DatStatus.NotInDat; string filename = dbDir.FullNameCase; ICompress checkZ = dbDir.FileType == FileType.Zip ? new Zip() : (ICompress) new SevenZ(); ZipReturn zr = checkZ.ZipFileOpen(filename, dbDir.FileModTimeStamp); if (zr == ZipReturn.ZipGood) { dbDir.ZipStatus = checkZ.ZipStatus; // to be Scanning a ZIP file means it is either new or has changed. // as the code below only calls back here if that is true. // // Level1: Only use header CRC's // Just get the CRC for the ZIP headers. // // Level2: Fully checksum changed only files // We know this file has been changed to do a full checksum scan. // // Level3: Fully checksum everything // So do a full checksum scan. if (_fs == null) { _fs = new FileScan(); } List <FileScan.FileResults> fr = _fs.Scan(checkZ, false, eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3); // add all of the file information from the zip file into scanDir for (int i = 0; i < checkZ.LocalFilesCount(); i++) { LocalFile lf = checkZ.GetLocalFile(i); RvFile tFile = new RvFile(DBTypeGet.FileFromDir(dbDir.FileType)) { Name = lf.Filename, ZipFileIndex = i, ZipFileHeaderPosition = lf.LocalHead, Size = lf.UncompressedSize, CRC = lf.CRC, FileModTimeStamp = lf.LastModified }; // all levels read the CRC from the ZIP header tFile.SetStatus(chechingDatStatus, GotStatus.Got); tFile.FileStatusSet(FileStatus.SizeFromHeader | FileStatus.CRCFromHeader); if (fr[i].FileStatus != ZipReturn.ZipGood) { thWrk.Report(new bgwShowCorrupt(fr[i].FileStatus, filename + " : " + lf.Filename)); tFile.GotStatus = GotStatus.Corrupt; } else { tFile.HeaderFileType = fr[i].HeaderFileType; tFile.SHA1 = fr[i].SHA1; tFile.MD5 = fr[i].MD5; tFile.AltSize = fr[i].AltSize; tFile.AltCRC = fr[i].AltCRC; tFile.AltSHA1 = fr[i].AltSHA1; tFile.AltMD5 = fr[i].AltMD5; if (fr[i].CRC != null) { tFile.FileStatusSet(FileStatus.CRCFromHeader); if (eScanLevel == EScanLevel.Level2 || eScanLevel == EScanLevel.Level3) { tFile.FileStatusSet(FileStatus.CRCVerified); } } tFile.FileStatusSet( FileStatus.SizeVerified | (fr[i].HeaderFileType != HeaderFileType.Nothing ? FileStatus.HeaderFileTypeFromHeader : 0) | (fr[i].SHA1 != null ? FileStatus.SHA1Verified : 0) | (fr[i].MD5 != null ? FileStatus.MD5Verified : 0) | (fr[i].AltSize != null ? FileStatus.AltSizeVerified : 0) | (fr[i].AltCRC != null ? FileStatus.AltCRCVerified : 0) | (fr[i].AltSHA1 != null ? FileStatus.AltSHA1Verified : 0) | (fr[i].AltMD5 != null ? FileStatus.AltMD5Verified : 0) ); } fileDir.ChildAdd(tFile); } } else if (zr == ZipReturn.ZipFileLocked) { thWrk.Report(new bgwShowError(filename, "Zip File Locked")); dbDir.FileModTimeStamp = 0; dbDir.GotStatus = GotStatus.FileLocked; } else { thWrk.Report(new bgwShowCorrupt(zr, filename)); dbDir.GotStatus = GotStatus.Corrupt; } checkZ.ZipFileClose(); return(fileDir); }
void IThreadPoolHelper <T> .QueueMultipleUserWorkItemsAndWaitForCompletion(int maximumThreads, ThreadWorker <T> callback, List <T> parameters) { QueueMultipleUserWorkItemsAndWaitForCompletion(maximumThreads, TimeSpan.FromMilliseconds(-1), callback, parameters); }
public override bool Equals(object obj) { ThreadWorker temp = obj as ThreadWorker; return(temp == null ? false : Equals(temp)); }
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(); } } } }