public Page WaitPage(int pageno, ForegroundWorker bgw) { try { if (!wl.TestAndSet()) { try { if (!archivedPages.IsPageArchived(pageno)) { var s = new BGWSerializer(bgw); var k = s.GetKey(); var ret = SavePage(pageno, new WrapBGW(s, k)); s.Commit(k); if (!ret) return null; } } catch { throw; } finally { wl.StopRunning(); } } else if (!archivedPages.IsPageArchived(pageno)) { archivedPages.Request(pageno); do { System.Threading.Thread.Sleep(1000); if (archivedPages.Failed()) return null; } while (!archivedPages.IsPageArchived(pageno)); } return GetPage(pageno, Parser.Is2x(pageno)); } catch { return null; } }
public void ResumeWork(ForegroundWorker bgw2, int startPage, int lastPage) { var bgw = new BGWSerializer(bgw2); while (wl.TestAndSet()) { System.Threading.Thread.Sleep(1000); } try { bool missedRound = false; startPage = ValidRange(startPage); int pagesToParse = lastPage - startPage + 1; int currentPage = archivedPages.FindLowestPage(startPage, lastPage);; var manager = new Writer.PageSavesManager(archivedPages.GetParseCount(startPage, lastPage), bgw2); if (currentPage > lastPage) { bgw2.ReportProgress(100, "Range already archived!"); return; } manager.CurrentProgress = (int)(((float)(manager.PagesParsed) / (float)(pagesToParse)) * 100.0f); if (!bgw2.CancellationPending) { bgw2.ReportProgress(manager.CurrentProgress, "Starting archive operation at page " + startPage); } else { bgw2.ReportProgress(manager.CurrentProgress, "Operation cancelled."); return; } while (true) { if (missedRound) { currentPage = manager.MissedPagesTop(); manager.CurrentProgress = (int)(((float)(manager.PagesParsed) / (float)(pagesToParse)) * 100.0f); } if (!bgw2.CancellationPending) { if (currentPage != startPage) bgw2.ReportProgress(manager.CurrentProgress, "Resuming from " + currentPage); } else { bgw2.ReportProgress(manager.CurrentProgress, "Operation cancelled."); return; } while (true) { UInt64 k = bgw.GetKey(); manager.ExpectWorker(); System.Threading.ThreadPool.QueueUserWorkItem(LaunchThreadedSave, new ThreadedSaveParams { Request = false, BGW = bgw, BGWKey = k, CurrentPage = currentPage, Manager = manager, PagesToParse = pagesToParse }); if (missedRound) { if (manager.MissedPagesCount() == 0) break; currentPage = manager.MissedPagesPop(); } else { if (currentPage >= lastPage) break; currentPage = ValidRange(archivedPages.FindLowestPage(currentPage + 1, lastPage)); } } while (!manager.WaitForWorkers() && !bgw2.CancellationPending) { Thread.Sleep(1); //since we run alongside the threadpool we have to be quick about things var req = (archivedPages.GetRequest()); if (req != 0) { UInt64 k = bgw.GetKey(); bgw.ReportProgress(k, manager.CurrentProgress, "Responding to user request for page " + req); LaunchThreadedSave(new ThreadedSaveParams { Request = true, BGW = bgw, BGWKey = k, CurrentPage = req, Manager = manager, PagesToParse = pagesToParse }); if(!archivedPages.IsPageArchived(req)) archivedPages.FailFlag(); } } while (!manager.WaitForWorkers()) { Thread.Sleep(1); } if (bgw2.CancellationPending || manager.MissedPagesCount() == 0) break; missedRound = true; bgw2.ReportProgress(manager.CurrentProgress, "Missed " + manager.MissedPagesCount() + " pages. Iterating through missed queue."); } if (bgw2.CancellationPending) bgw2.ReportProgress(manager.CurrentProgress, "Operation cancelled."); else bgw2.ReportProgress(100, "Operation completed."); } catch { throw; } finally { wl.StopRunning(); } }