I'm trying to get into the asynchronous thing. I'd like to make one of my methods asynchronous because it takes a while to finish so I tried this:
public static async Task GenerateExcelFile(HashSet<string> codes, ContestViewModel model)
{
var totalCodeToDistribute = model.NbrTotalCodes - (model.NbrCodesToPrinter + model.NbrCodesToClientService);
if (model.NbrTotalCodes > 0)
{
using (var package = new ExcelPackage())
{
await DoStuff(some, variables, here);
package.SaveAs(fileInfo);
}
}
}
So I could call it in my controller like that:
await FilesGenerationUtils.GenerateExcelFile(uniqueCodesHashSet, model);
but when it comes to the "await" keyword, it says that "Type void is not awaitable"
Is that a way to await for void methods or is it not a best practice? And if so, what would be the best way to do it?
The controller:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Index(ContestViewModel model)
{
var contentRootPath = _hostingEnvironment.ContentRootPath;
DirectoryUtils.OutputDir = new DirectoryInfo(contentRootPath + Path.DirectorySeparatorChar
+ "_CodesUniques" + Path.DirectorySeparatorChar
+ model.ProjectName +
Path.DirectorySeparatorChar
+ "_Codes");
var directory = DirectoryUtils.OutputDir;
var selectedAnswer = model.SelectedAnswer;
var uniqueCodesHashSet = new HashSet<string>();
try
{
while (uniqueCodesHashSet.Count < model.NbrTotalCodes)
{
var generatedString = RandomStringsUtils.Generate(model.AllowedChars, model.UniqueCodeLength);
uniqueCodesHashSet.Add(generatedString.ToUpper());
}
#region FOR TXT FILES
if (selectedAnswer == FileExtension.TXT.GetStringValue())
{
await FilesGenerationUtils.GenerateTxtFiles(uniqueCodesHashSet, model, directory);
}
#endregion
#region FOR XLSX FILES
if (selectedAnswer == FileExtension.XLSX.GetStringValue())
{
await FilesGenerationUtils.GenerateExcelFile(uniqueCodesHashSet, model);
}
#endregion
return View();
}
catch (Exception ex)
{
Console.Write(ex);
}
return View();
}
If I've understood what you're all saying, I must create a method that would be awaitable. Am I going right if I go with something like this:
public static Task DoStuff(ExcelWorksheet sheet, HashSet<string> codes, int rowIndex, int count, int maxRowValue)
{
foreach (var code in codes)
{
sheet.Row(rowIndex);
sheet.Cells[rowIndex, 1].Value = code;
rowIndex++;
count++;
if (rowIndex == maxRowValue && count < (codes.Count - 1))
{
sheet.InsertColumn(1, 1);
rowIndex = 1;
}
}
//What should be returned?!
return null;
}