哪种方法可以异步运行多个任务,具有最佳性能?
在我的情况下,我必须阅读多个文件夹,检索它们的大小和文件数。
我注意到一段时间后这个过程变慢了。
我想知道这是否是处理等待它们的长时间操作的最佳方式,或者是否有更好的方法。
这是我的代码:
static void Main(string[] args)
{
try
{
DbManager dbManager = new DbManager();
DataTable _dtDirectoriesToWork = dbManager.SelectDirectoriesToCount();
var _tasks = new List<Task<ReadDataResults>>();
foreach (DataRow _Directory in _dtDirectoriesToWork.Rows)
{
ReadArchiveRunner _RunnerArchive =
new ReadArchiveRunner(_Directory["PathDirectory"].ToString(), _Directory["ID"].ToString());
_RunnerArchive.ProcessReadPath();
_tasks.Add(_RunnerArchive.ReadTask);
}
Task.WaitAll(_tasks.ToArray());
//Operations after finished
Console.ReadLine();
}
catch (Exception exc)
{
}
}
ReadArchiveRunner Class:
class ReadArchiveRunner
{
DbManager _SqlDbman = new DbManager();
MailManager _Mailman = new MailManager();
LogManager _Logman = new LogManager();
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern bool GetDiskFreeSpace(string lpRootPathName,
out uint lpSectorsPerCluster,
out uint lpBytesPerSector,
out uint lpNumberOfFreeClusters,
out uint lpTotalNumberOfClusters);
private uint _lpSectorsPerCluster;
private uint _lpBytesPerSector;
private uint _lpNumberOfFreeClusters;
private uint _lpTotalNumberOfClusters;
public Task<ReadDataResults> ReadTask { get; set; }
private string DirecotryToScan { get; set; }
private string IDDirecotryToScan { get; set; }
string _Error = null;
public void ProcessReadPath()
{
ReadTask = Task.Run(() => ReadPath());
}
public ReadArchiveRunner(string Directory, string IDDirectory)
{
DirecotryToScan = Directory;
IDDirecotryToScan = IDDirectory;
}
private ReadDataResults ReadPath()
{
try
{
Int64 sizeondisk = 0;
uint _ClusterDimensions = 0;
DirectoryInfo DirInfo = new DirectoryInfo(DirecotryToScan);
Stopwatch sw = new Stopwatch();
sw.Start();
Int64 ttl = 0;
Int32 fileCount = 0;
GetDiskFreeSpace(DirecotryToScan, out _lpSectorsPerCluster, out _lpBytesPerSector, out _lpNumberOfFreeClusters, out _lpTotalNumberOfClusters);
_ClusterDimensions = _lpSectorsPerCluster * _lpBytesPerSector;
IEnumerable<FileInfo> _dirFileInfo = DirInfo.EnumerateFiles("*", SearchOption.AllDirectories);
foreach (FileInfo fi in _dirFileInfo)
{
if (!fi.Attributes.HasFlag(FileAttributes.System))
{
ttl += fi.Length;
sizeondisk += _ClusterDimensions * ((fi.Length + _ClusterDimensions - 1) / _ClusterDimensions);
fileCount++;
}
}
sw.Stop();
string resultGbDimensioni = FormatBytes(ttl);
string resultGbDimensioniSuDisco = FormatBytes(sizeondisk);
ReadDataResults _RecordResult = new ReadDataResults
{
IDDirectory = IDDirecotryToScan,
TempoTotale = FormatMilliseconds(sw.ElapsedMilliseconds),
TotaleFiles = fileCount,
TotaleDimensione = ttl,
TotaleDimensioneSuDisco = sizeondisk,
TotaleDimensioneFormatted = resultGbDimensioni,
TotaleDimensioneSuDiscoFormatted = resultGbDimensioniSuDisco
};
Console.WriteLine(DirecotryToScan +
"\Tempo Totale: " + _RecordResult.TempoTotale +
"\nTotale Dimensione: " + _RecordResult.TotaleDimensione + " " + _RecordResult.TotaleDimensioneFormatted +
"\nTempo Dimensione Su Disco: " + _RecordResult.TotaleDimensioneSuDisco + " " + _RecordResult.TotaleDimensioneSuDiscoFormatted +
"\nTotale Files: " + _RecordResult.TotaleFiles + "\n");
_SqlDbman.InsertRecordReadData(_RecordResult, out _Error);
return _RecordResult;
}
catch (Exception Exc)
{
string _ErrorMessage = DirecotryToScan +
"\n " + Exc.Message;
Console.WriteLine(_ErrorMessage);
_Logman.WriteToLog(_ErrorMessage);
return null;
}
finally
{
}
}
private string FormatMilliseconds(long MilliSeconds)
{
TimeSpan _t = TimeSpan.FromMilliseconds(MilliSeconds);
string _TimeFormatted = string.Format("{0:D2}h:{1:D2}m:{2:D2}s:{3:D3}ms",
_t.Hours,
_t.Minutes,
_t.Seconds,
_t.Milliseconds);
return _TimeFormatted;
}
private string FormatBytes(long bytes)
{
string[] Suffix = { "B", "KB", "MB", "GB", "TB" };
int i;
double dblSByte = bytes;
for (i = 0; i < Suffix.Length && bytes >= 1024; i++, bytes /= 1024)
{
dblSByte = bytes / 1024.0;
}
return String.Format("{0:0.##} {1}", dblSByte, Suffix[i]);
}
}