I copy files in a Zip archive
(3td part library to get the progress) with a BackgroundWorker
so I not block the UI and I can upgrade the ProgressBar
or cancel the copy.
This is the code of BackgroundWorker
, source, target and name are general variable:
private void _backgroundWorkerB1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
//Check if the source directory exist
if (Directory.Exists(source) == false)
{
e.Result = "NotExist";
return;
}
//If the target not exist I will create it
if (Directory.Exists(target) == false)
{
Directory.CreateDirectory(target);
}
string filename = target + "\\" +
DateTime.Now.ToString("yyyy'-'MM'-'dd'_'HH'_'mm'_'ss") +
"-" + name + ".zip";
// 3td part library
ArchivioB1.FileName = filename;
ArchivioB1.OpenArchive(System.IO.FileMode.Create);
ArchivioB1.OnOverallProgress += new BaseArchiver
.OnOverallProgressDelegate(ArchivioB1_OnOverallProgress);
// Source directory
ArchivioB1.BaseDir = source;
// Copy all files
ArchivioB1.AddFiles("*.*");
// Close
ArchivioB1.CloseArchive();
}
catch (Exception ex)
{
e.Result = "Error";
return;
}
}
I need to modify the code to make it in parallel from a DataGrid
. I will have a DataGrid
on the first column the name of the file, on the second a progress bar, on third the State and on fourth the destination of file.
The DataGrid
can have an undefined rows and these rows can be more than cores of the CPU. How can I run the same function in parallel, and if the rows are more than the CPU cores, the system have to wait till one of it will be free and continue with the next copy?
I don't understand why the community have to close the question when isn't duplicate like they think, in any case if someone need to copy files in archive parallely with a progress Hereafter final Edit with working code:
private async void btBackup_Click(object sender, RoutedEventArgs e)
{
btBackup.IsEnabled = false;
btCancel.IsEnabled = true;
var row_list1 = GetDataGridRows(dgwStation);
List<Task> tasks = new List<Task>();
ZipForge[] ZipList = new ZipForge[DataGridItemsList.Count];
tokenSource = new CancellationTokenSource();
foreach (DataGridRow single_row in row_list1)
{
int riga = single_row.GetIndex();
ZipList[riga] = new ZipForge();
tasks.Add(Task.Run(() => CopyTest(riga,ZipList[riga])));
}
await Task.WhenAll(tasks);
if (generalerror)
tbkStato.Text = "Completed with error";
else if (tbkStato.Text != "Cancelled")
tbkStato.Text = "Completed";
}
private void btCancel_Click(object sender, RoutedEventArgs e)
{
try
{
if (tokenSource != null) //se il token non è nullo, posso chiedere la cancellazione
{
//tbkStato.Text = "Cancelled";
tokenSource.Cancel();
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
public void CopyTest(int rowindex, ZipForge ArchivioB1)
{
string nome1 = "";
try
{
//Takes data from DatGridItemsList
string source = DataGridItemsList[rowindex].Source, target = DataGridItemsList[rowindex].Target, filename = DataGridItemsList[rowindex].FileName;
tbkStato.Dispatcher.Invoke(new Action(() => { tbkStato.Text = "Check source"; }));
if (Directory.Exists(source) == false)
{
DataGridItemsList[rowindex].State = "Not Exist";
dgwStation.Dispatcher.Invoke(new Action(() => { dgwStation.Items.Refresh(); }));
generalerror = true;
return;
}
tbkStato.Dispatcher.Invoke(new Action(() => { tbkStato.Text = "Check target"; }));
if (Directory.Exists(target) == false)
{
Directory.CreateDirectory(target);
}
DataGridItemsList[rowindex].State = "creating Zip";
dgwStation.Dispatcher.Invoke(new Action(() => { dgwStation.Items.Refresh(); }));
nome1 = target + "\\" + DateTime.Now.ToString("yyyy'-'MM'-'dd'_'HH'_'mm'_'ss") + "-" + filename + ".zip";
ArchivioB1.FileName = nome1;
ArchivioB1.OpenArchive(System.IO.FileMode.Create,FileAccess.Write);
ArchivioB1.Comment = rowindex.ToString();
ArchivioB1.OnOverallProgress += new BaseArchiver.OnOverallProgressDelegate(ArchivioB1_OnOverallProgress);
ArchivioB1.BaseDir = source;
// Copia tutti i file nell'archivio creato
ArchivioB1.AddFiles("*.*");
if (tokenSource.Token.IsCancellationRequested) //Interruzzione dell'utente
{
tokenSource.Token.ThrowIfCancellationRequested();
}
else
{
ArchivioB1.CloseArchive();
DataGridItemsList[rowindex].State = "Completed";
dgwStation.Dispatcher.Invoke(new Action(() => { dgwStation.Items.Refresh(); }));
}
}
catch (OperationCanceledException)
{
ArchivioB1.CloseArchive();
if (File.Exists(nome1))
File.Delete(nome1);
DataGridItemsList[rowindex].State = "Cancelled";
dgwStation.Dispatcher.Invoke(new Action(() => { dgwStation.Items.Refresh(); }));
tbkStato.Dispatcher.Invoke(new Action(() => { tbkStato.Text = "Cancelled"; }));
return;
}
catch (Exception ex)
{
ArchivioB1.CloseArchive();
if (File.Exists(nome1))
File.Delete(nome1);
DataGridItemsList[rowindex].State = ex.Message.ToString();
dgwStation.Dispatcher.Invoke(new Action(() => { dgwStation.Items.Refresh(); }));
generalerror = true;
return;
}
}
private void ArchivioB1_OnOverallProgress(object sender, double progress, TimeSpan timeElapsed, TimeSpan timeLeft, ProcessOperation operation, ProgressPhase progressPhase, ref bool cancel)
{
if (tokenSource.Token.IsCancellationRequested) //Interruzzione dell'utente
{
cancel = true;
//tokenSource.Token.ThrowIfCancellationRequested();
}
ZipForge Archivio = (ZipForge)sender;
int indice = Convert.ToInt32(Archivio.Comment);
DataGridItemsList[indice].Progress = Convert.ToInt32(progress);
dgwStation.Dispatcher.Invoke(new Action(() => { dgwStation.Items.Refresh(); }));
}