使用多个异步/等待复制文件时出现问题



我有一个DataGrid,它由一个列表填充,其中的项目具有在zip中复制文件的源和目标方向。

这是一个按钮中的代码,我在其中为DataGrid的每个项目进行循环,以开始并行复制。

var row_list = GetDataGridRows(dgwStation);
tokenSource = new CancellationTokenSource();
var tasks = new List<Task<string>>();
//All items of DataGrid
foreach (DataGridRow single_row in row_list)
{
var row = single_row.GetIndex();
tasks.Add(TaskOperationBackupOffline(row, tokenSource.Token));
}
btBackup.IsEnabled = false; 
btCancel.IsEnabled = true; 
await Task.WhenAll(tasks); //Wait all the tasks are finished

这是TaskOperationBackupOffline:的代码

private async Task<string> TaskOperationBackupOffline(int rowindex, CancellationToken ct)
{
try
{
//Read all the datas
string source=StationItemsList[rowindex].ControlPath,
target = StationItemsList[rowindex].Destination,
filename = StationItemsList[rowindex].StationName;
//Source directory control
StationItemsList[rowindex].State = Chiavi.dict["backupon_controlorigin"].ToString();
dgwStation.Items.Refresh();
//If the source not exist, exit 
if (Directory.Exists(source) == false)
{
StationItemsList[rowindex].State = Chiavi
.dict["backupstate_source"].ToString();
dgwStation.Items.Refresh();
generalerror = true;
return "source error";
}
//Target directory control
StationItemsList[rowindex].State = Chiavi.dict["backupon_controldestinationdata"].ToString();
dgwStation.Items.Refresh();
//If not exist I create it
if (Directory.Exists(target) == false)
{
Directory.CreateDirectory(target);
}
if (ct.IsCancellationRequested) //Cancellation by user
{
ct.ThrowIfCancellationRequested();
}
StationItemsList[rowindex].State = Chiavi.dict["backupon_preparation"].ToString();
dgwStation.Items.Refresh();
string nome1 = target + "\";
nome1 += DateTime.Now.Year;
nome1 += "-";
nome1 += voidGeneral.ConversioneDecimale(DateTime.Now.Month);
nome1 += "-";
nome1 += voidGeneral.ConversioneDecimale(DateTime.Now.Day);
nome1 += "_";
nome1 += voidGeneral.ConversioneDecimale(DateTime.Now.Hour);
nome1 += "_";
nome1 += voidGeneral.ConversioneDecimale(DateTime.Now.Minute);
nome1 += "_";
nome1 += voidGeneral.ConversioneDecimale(DateTime.Now.Second);
nome1 += "-";
nome1 += filename;
nomearchivio = nome1 + ".zip";
// Name of zip file with all the path
ArchivioB1.FileName = nome1 + ".zip";
// Create archive
ArchivioB1.OpenArchive(System.IO.FileMode.Create);
ArchivioB1.Comment = rowindex.ToString(); 
ArchivioB1.OnOverallProgress += new BaseArchiver
.OnOverallProgressDelegate(ArchivioB1_OnOverallProgress);
// Source directory 
ArchivioB1.BaseDir = source;
StationItemsList[rowindex].State = Chiavi.dict["backupon_createZIP"].ToString();
dgwStation.Items.Refresh();
if (ct.IsCancellationRequested) //Cancellation by user
{
ct.ThrowIfCancellationRequested();
}
// Copy all files in the zip archive
ArchivioB1.AddFiles("*.*");
// Close zip file
ArchivioB1.CloseArchive();
await Task.Delay(50);
return "Complete";
}
catch (OperationCanceledException)
{
StationItemsList[rowindex].State = "Cancelled";
dgwStation.Items.Refresh();
tbkStato.Text = Chiavi.dict["backupstate_cancelled"].ToString();
return "Cancelled";
}
catch (Exception ex)
{
StationItemsList[rowindex].State = ex.Message.ToString();
dgwStation.Items.Refresh();
generalerror = true;
return "Error";
}
}

当我点击按钮时,UI立即冻结,而不是异步,最后只处理第一个项目。

我做错了什么?

向方法添加async关键字不会使其异步运行。这只意味着可以等待该方法——你可能想看看它的实际含义。要使该方法无阻塞运行,您必须将整个内容包装在类似的东西中

return Task.Run(() => 
{
// your code goes here 
});

然后,逻辑将实际在不同的线程上运行。

一旦您不再使用UI线程,就无法直接调用UI元素上的方法。您必须使用Invoke。

最新更新