Make thread safe and integrate with Libation UI

This commit is contained in:
Michael Bucari-Tovo 2022-05-14 14:39:46 -06:00
parent 50c35ed519
commit 73a5d76503
5 changed files with 66 additions and 26 deletions

View File

@ -74,7 +74,7 @@
this.splitContainer1 = new System.Windows.Forms.SplitContainer(); this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.button1 = new System.Windows.Forms.Button(); this.button1 = new System.Windows.Forms.Button();
this.panel1 = new System.Windows.Forms.Panel(); this.panel1 = new System.Windows.Forms.Panel();
this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessBookQueue(); this.processBookQueue1 = new LibationWinForms.ProcessQueue.ProcessQueueControl();
this.menuStrip1.SuspendLayout(); this.menuStrip1.SuspendLayout();
this.statusStrip1.SuspendLayout(); this.statusStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit(); ((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
@ -470,7 +470,6 @@
this.button1.TabIndex = 8; this.button1.TabIndex = 8;
this.button1.Text = "button1"; this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true; this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.button1_Click);
// //
// panel1 // panel1
// //
@ -565,7 +564,7 @@
private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem removeToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem liberateVisible2ToolStripMenuItem; private System.Windows.Forms.ToolStripMenuItem liberateVisible2ToolStripMenuItem;
private System.Windows.Forms.SplitContainer splitContainer1; private System.Windows.Forms.SplitContainer splitContainer1;
private LibationWinForms.ProcessQueue.ProcessBookQueue processBookQueue1; private LibationWinForms.ProcessQueue.ProcessQueueControl processBookQueue1;
private System.Windows.Forms.Panel panel1; private System.Windows.Forms.Panel panel1;
private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button1;
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
namespace LibationWinForms namespace LibationWinForms
@ -7,11 +8,12 @@ namespace LibationWinForms
{ {
private void Configure_Liberate() { } private void Configure_Liberate() { }
private async void beginBookBackupsToolStripMenuItem_Click(object sender, EventArgs e) //GetLibrary_Flat_NoTracking() may take a long time on a hugh library. so run in new thread
=> await BookLiberation.ProcessorAutomationController.BackupAllBooksAsync(); private void beginBookBackupsToolStripMenuItem_Click(object sender, EventArgs e)
=> Task.Run(()=>processBookQueue1.AddDownloadDecrypt(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()));
private async void beginPdfBackupsToolStripMenuItem_Click(object sender, EventArgs e) private void beginPdfBackupsToolStripMenuItem_Click(object sender, EventArgs e)
=> await BookLiberation.ProcessorAutomationController.BackupAllPdfsAsync(); => Task.Run(() => processBookQueue1.AddDownloadPdf(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()));
private async void convertAllM4bToMp3ToolStripMenuItem_Click(object sender, EventArgs e) private async void convertAllM4bToMp3ToolStripMenuItem_Click(object sender, EventArgs e)
{ {
@ -24,7 +26,7 @@ namespace LibationWinForms
MessageBoxButtons.YesNo, MessageBoxButtons.YesNo,
MessageBoxIcon.Warning); MessageBoxIcon.Warning);
if (result == DialogResult.Yes) if (result == DialogResult.Yes)
await BookLiberation.ProcessorAutomationController.ConvertAllBooksAsync(); await Task.Run(() => processBookQueue1.AddConvertMp3(ApplicationServices.DbContexts.GetLibrary_Flat_NoTracking()));
} }
} }
} }

View File

@ -1,4 +1,5 @@
using LibationFileManager; using ApplicationServices;
using LibationFileManager;
using LibationWinForms.ProcessQueue; using LibationWinForms.ProcessQueue;
using System; using System;
using System.Windows.Forms; using System.Windows.Forms;
@ -9,7 +10,7 @@ namespace LibationWinForms
{ {
private void Configure_ProcessQueue() private void Configure_ProcessQueue()
{ {
//splitContainer1.Panel2Collapsed = true; productsGrid.LiberateClicked += (_, lb) => processBookQueue1.AddDownloadDecrypt(lb);
processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut; processBookQueue1.popoutBtn.Click += ProcessBookQueue1_PopOut;
} }
@ -39,10 +40,5 @@ namespace LibationWinForms
this.Focus(); this.Focus();
} }
} }
private void button1_Click(object sender, EventArgs e)
{
processBookQueue1.AddDownloadDecrypt(productsGrid.List);
}
} }
} }

View File

@ -3,6 +3,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
@ -12,7 +13,7 @@ namespace LibationWinForms.ProcessQueue
{ {
private TrackedQueue<ProcessBook> Queue = new(); private TrackedQueue<ProcessBook> Queue = new();
private readonly LogMe Logger; private readonly LogMe Logger;
private SynchronizationContext SyncContext { get; } = SynchronizationContext.Current;
private int QueuedCount private int QueuedCount
{ {
set set
@ -70,16 +71,48 @@ namespace LibationWinForms.ProcessQueue
CompletedCount = 0; CompletedCount = 0;
} }
public void AddDownloadPdf(IEnumerable<DataLayer.LibraryBook> entries)
{
Action<IEnumerable<DataLayer.LibraryBook>> makeAll = (lb) =>
{
foreach (var entry in entries)
AddDownloadPdf(entry);
};
//IEnumerable<DataLayer.LibraryBook> are run on non-ui thread, so send collection to UI first
PassToUIThread(entries, makeAll);
}
public void AddDownloadDecrypt(IEnumerable<DataLayer.LibraryBook> entries) public void AddDownloadDecrypt(IEnumerable<DataLayer.LibraryBook> entries)
{ {
foreach (var entry in entries) Action<IEnumerable<DataLayer.LibraryBook>> makeAll = (lb) =>
AddDownloadDecrypt(entry); {
foreach (var entry in entries)
AddDownloadDecrypt(entry);
};
//IEnumerable<DataLayer.LibraryBook> are run on non-ui thread, so send collection to UI first
PassToUIThread(entries, makeAll);
} }
public void AddConvertMp3(IEnumerable<DataLayer.LibraryBook> entries) public void AddConvertMp3(IEnumerable<DataLayer.LibraryBook> entries)
{ {
foreach (var entry in entries) Action<IEnumerable<DataLayer.LibraryBook>> makeAll = (lb) =>
AddConvertMp3(entry); {
foreach (var entry in entries)
AddConvertMp3(entry);
};
//IEnumerable<DataLayer.LibraryBook> are run on non-ui thread, so send collection to UI first
PassToUIThread(entries, makeAll);
}
public void AddDownloadPdf(DataLayer.LibraryBook libraryBook)
{
if (Queue.Any(b => b?.LibraryBook?.Book?.AudibleProductId == libraryBook.Book.AudibleProductId))
return;
ProcessBook pbook = new(libraryBook, Logger);
pbook.PropertyChanged += Pbook_DataAvailable;
pbook.AddDownloadPdf();
AddToQueue(pbook);
} }
public void AddDownloadDecrypt(DataLayer.LibraryBook libraryBook) public void AddDownloadDecrypt(DataLayer.LibraryBook libraryBook)
@ -105,6 +138,15 @@ namespace LibationWinForms.ProcessQueue
AddToQueue(pbook); AddToQueue(pbook);
} }
private void PassToUIThread(IEnumerable<DataLayer.LibraryBook> libraryBooks, Action<IEnumerable<DataLayer.LibraryBook>> onComplete)
{
void OnSendOrPostCallback(object asyncArgs)
{
onComplete((IEnumerable<DataLayer.LibraryBook>)asyncArgs);
}
SyncContext.Send(OnSendOrPostCallback, libraryBooks);
}
private void AddToQueue(ProcessBook pbook) private void AddToQueue(ProcessBook pbook)
{ {
Queue.Enqueue(pbook); Queue.Enqueue(pbook);
@ -164,8 +206,8 @@ namespace LibationWinForms.ProcessQueue
} }
private void UpdateProgressBar() private void UpdateProgressBar()
{ {
toolStripProgressBar1.Maximum = Queue.Count; toolStripProgressBar1.Maximum = Queue.Count;
toolStripProgressBar1.Value = Queue.Completed.Count; toolStripProgressBar1.Value = Queue.Completed.Count;
} }
private void cancelAllBtn_Click(object sender, EventArgs e) private void cancelAllBtn_Click(object sender, EventArgs e)

View File

@ -36,8 +36,10 @@ namespace LibationWinForms
// VS has improved since then with .net6+ but I haven't checked again // VS has improved since then with .net6+ but I haven't checked again
#endregion #endregion
public partial class ProductsGrid : UserControl public partial class ProductsGrid : UserControl
{ {
public event EventHandler<LibraryBook> LiberateClicked;
/// <summary>Number of visible rows has changed</summary> /// <summary>Number of visible rows has changed</summary>
public event EventHandler<int> VisibleCountChanged; public event EventHandler<int> VisibleCountChanged;
@ -76,7 +78,7 @@ namespace LibationWinForms
return; return;
if (e.ColumnIndex == liberateGVColumn.Index) if (e.ColumnIndex == liberateGVColumn.Index)
await Liberate_Click(getGridEntry(e.RowIndex)); Liberate_Click(getGridEntry(e.RowIndex));
else if (e.ColumnIndex == tagAndDetailsGVColumn.Index) else if (e.ColumnIndex == tagAndDetailsGVColumn.Index)
Details_Click(getGridEntry(e.RowIndex)); Details_Click(getGridEntry(e.RowIndex));
else if (e.ColumnIndex == descriptionGVColumn.Index) else if (e.ColumnIndex == descriptionGVColumn.Index)
@ -128,7 +130,7 @@ namespace LibationWinForms
displayWindow.Show(this); displayWindow.Show(this);
} }
private static async Task Liberate_Click(GridEntry liveGridEntry) private void Liberate_Click(GridEntry liveGridEntry)
{ {
var libraryBook = liveGridEntry.LibraryBook; var libraryBook = liveGridEntry.LibraryBook;
@ -144,8 +146,7 @@ namespace LibationWinForms
return; return;
} }
// else: liberate LiberateClicked?.Invoke(this, liveGridEntry.LibraryBook);
await liveGridEntry.DownloadBook();
} }
private static void Details_Click(GridEntry liveGridEntry) private static void Details_Click(GridEntry liveGridEntry)