Как дождаться окончания работы асинхронных методов. [Решено]
Цитата: Владимир от 14.04.2021, 00:38Добрый день, есть "клик" по кнопке, который много раз вызывает метод для удаления папок/файлов "FolderRemover" который при успешном удаление добавляет размер удалённого файла к переменной "RemovedSize", после того как "клик" вызвал все удаления, он вызывает метод который конвертирует переменную "RemovedSize" в кб, мб, и т.д. Далее конвертированная переменная выводиться. Проблема в том что метод "FolderRemover" не успевает доработать, а уже вызывается метод конвертации, соответственно не весь удалённый размер выводиться. Помогите пожалуйста, как можно сделать так чтобы конвертация вызвалась только после того как "FolderRemover" закончил свою работу?
Код:
[spoiler title="Мой код"]public long RemovedSize = 0; public string RemovedSizeInt; //Удаляльщик public async void FolderRemover(string Location) { await Task.Run(() => { if (Directory.Exists($"{Location}")) { try { string[] Files; string[] Dirs; Files = Directory.GetFiles($"{Location}", "*", SearchOption.AllDirectories); Dirs = Directory.GetDirectories($"{Location}", "*", SearchOption.AllDirectories); foreach (string s in Files) { FileInfo file = new FileInfo(s); long FileSize = file.Length; try { File.Delete(s); RemovedSize += FileSize; } catch { } } try { Directory.Delete($"{Location}", true); } catch { } } catch { } } }); } //Конвертер, конвертирует очищенные байты async void Converter() { await Task.Run(() => { string[] suf = { " Byt", " KB", " MB", " GB", " TB", " PB", " EB" }; long bytes = Math.Abs(RemovedSize); int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); double num = Math.Round(bytes / Math.Pow(1024, place), 1); DiskRamCleanerButton.Text = "Очищено " + Math.Sign(RemovedSize) * num + suf[place]; }); } string LocalApp = Environment.GetEnvironmentVariable("LocalAppData"); //Кнопка async void ExUpKeybButton_Click(object sender, EventArgs e) { await Task.Run(() => { FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Crashpad"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\blob_storage"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\BudgetDatabase"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Cache"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Code Cache"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\data_reduction_proxy_leveldb"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\databases"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\File System"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GCM Store"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GPUCache"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\IndexedDB"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsMostVisited"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsRecentClosed"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Local Storage"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Platform Notifications"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Value Store"); FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Worker"); } Converter(); }); }[/spoiler]
Либо же как можно написать по-другому этот код, рассмотрю все варианты)
Добрый день, есть "клик" по кнопке, который много раз вызывает метод для удаления папок/файлов "FolderRemover" который при успешном удаление добавляет размер удалённого файла к переменной "RemovedSize", после того как "клик" вызвал все удаления, он вызывает метод который конвертирует переменную "RemovedSize" в кб, мб, и т.д. Далее конвертированная переменная выводиться. Проблема в том что метод "FolderRemover" не успевает доработать, а уже вызывается метод конвертации, соответственно не весь удалённый размер выводиться. Помогите пожалуйста, как можно сделать так чтобы конвертация вызвалась только после того как "FolderRemover" закончил свою работу?
Код:
public long RemovedSize = 0;
public string RemovedSizeInt;
//Удаляльщик
public async void FolderRemover(string Location)
{
await Task.Run(() =>
{
if (Directory.Exists($"{Location}"))
{
try
{
string[] Files;
string[] Dirs;
Files = Directory.GetFiles($"{Location}", "*", SearchOption.AllDirectories);
Dirs = Directory.GetDirectories($"{Location}", "*", SearchOption.AllDirectories);
foreach (string s in Files)
{
FileInfo file = new FileInfo(s);
long FileSize = file.Length;
try
{
File.Delete(s);
RemovedSize += FileSize;
}
catch { }
}
try
{
Directory.Delete($"{Location}", true);
}
catch { }
}
catch { }
}
});
}
//Конвертер, конвертирует очищенные байты
async void Converter()
{
await Task.Run(() =>
{
string[] suf = { " Byt", " KB", " MB", " GB", " TB", " PB", " EB" };
long bytes = Math.Abs(RemovedSize);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
DiskRamCleanerButton.Text = "Очищено " + Math.Sign(RemovedSize) * num + suf[place];
});
}
string LocalApp = Environment.GetEnvironmentVariable("LocalAppData");
//Кнопка
async void ExUpKeybButton_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Crashpad");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\blob_storage");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\BudgetDatabase");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Cache");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Code Cache");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\data_reduction_proxy_leveldb");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\databases");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\File System");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GCM Store");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GPUCache");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\IndexedDB");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsMostVisited");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsRecentClosed");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Local Storage");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Platform Notifications");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Value Store");
FolderRemover(LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Worker");
}
Converter();
});
}
Либо же как можно написать по-другому этот код, рассмотрю все варианты)
Цитата: Вася от 14.04.2021, 12:14Добрый день!
Метод "FolderRemover" у Вас асинхронный, поэтому, не дожидаясь его завершения, вызывается метод "Converter". Просто уберите асинхронность из этих (FolderRemover, Converter) методов. Если вам надо паралельно удалять папки, то можно это сделать с помощью "AsParallel".
[spoiler title="Как-то так"]public long RemovedSize = 0; public string RemovedSizeInt; //Удаляльщик public void FolderRemover(string Location) { if (Directory.Exists($"{Location}")) { try { string[] Files; string[] Dirs; Files = Directory.GetFiles($"{Location}", "*", SearchOption.AllDirectories); Dirs = Directory.GetDirectories($"{Location}", "*", SearchOption.AllDirectories); foreach (string s in Files) { FileInfo file = new FileInfo(s); long FileSize = file.Length; try { File.Delete(s); RemovedSize += FileSize; } catch { } } try { Directory.Delete($"{Location}", true); } catch { } } catch { } } } //Конвертер, конвертирует очищенные байты void Converter() { string[] suf = { " Byt", " KB", " MB", " GB", " TB", " PB", " EB" }; long bytes = Math.Abs(RemovedSize); int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024))); double num = Math.Round(bytes / Math.Pow(1024, place), 1); DiskRamCleanerButton.Text = "Очищено " + Math.Sign(RemovedSize) * num + suf[place]; } string LocalApp = Environment.GetEnvironmentVariable("LocalAppData"); //Кнопка async void ExUpKeybButton_Click(object sender, EventArgs e) { await Task.Run(() => { //Паралельно удаляем папки new List<string> { LocalApp + @"\Yandex\YandexBrowser\User Data\Crashpad", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\blob_storage", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\BudgetDatabase", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Cache", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Code Cache", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\data_reduction_proxy_leveldb", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\databases", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\File System", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GCM Store", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GPUCache", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\IndexedDB", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsMostVisited", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsRecentClosed", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Local Storage", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Platform Notifications", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Value Store", LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Worker", }.AsParallel().ForAll(FolderRemover); Invoke(new Action(Converter)); }); }[/spoiler]
Добрый день!
Метод "FolderRemover" у Вас асинхронный, поэтому, не дожидаясь его завершения, вызывается метод "Converter". Просто уберите асинхронность из этих (FolderRemover, Converter) методов. Если вам надо паралельно удалять папки, то можно это сделать с помощью "AsParallel".
public long RemovedSize = 0;
public string RemovedSizeInt;
//Удаляльщик
public void FolderRemover(string Location)
{
if (Directory.Exists($"{Location}"))
{
try
{
string[] Files;
string[] Dirs;
Files = Directory.GetFiles($"{Location}", "*", SearchOption.AllDirectories);
Dirs = Directory.GetDirectories($"{Location}", "*", SearchOption.AllDirectories);
foreach (string s in Files)
{
FileInfo file = new FileInfo(s);
long FileSize = file.Length;
try
{
File.Delete(s);
RemovedSize += FileSize;
}
catch { }
}
try
{
Directory.Delete($"{Location}", true);
}
catch { }
}
catch { }
}
}
//Конвертер, конвертирует очищенные байты
void Converter()
{
string[] suf = { " Byt", " KB", " MB", " GB", " TB", " PB", " EB" };
long bytes = Math.Abs(RemovedSize);
int place = Convert.ToInt32(Math.Floor(Math.Log(bytes, 1024)));
double num = Math.Round(bytes / Math.Pow(1024, place), 1);
DiskRamCleanerButton.Text = "Очищено " + Math.Sign(RemovedSize) * num + suf[place];
}
string LocalApp = Environment.GetEnvironmentVariable("LocalAppData");
//Кнопка
async void ExUpKeybButton_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
//Паралельно удаляем папки
new List<string> {
LocalApp + @"\Yandex\YandexBrowser\User Data\Crashpad",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\blob_storage",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\BudgetDatabase",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Cache",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Code Cache",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\data_reduction_proxy_leveldb",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\databases",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\File System",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GCM Store",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\GPUCache",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\IndexedDB",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsMostVisited",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\JumpListIconsRecentClosed",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Local Storage",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Platform Notifications",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Value Store",
LocalApp + @"\Yandex\YandexBrowser\User Data\Default\Service Worker",
}.AsParallel().ForAll(FolderRemover);
Invoke(new Action(Converter));
});
}
Цитата: Владимир от 14.04.2021, 13:15Спасибо, все работает, только не могу понять, почему когда я добавляю такой код, в "AsParallel", красным подчёркивает "FileRemover", с ошибкой: "Аргумент 2: не удалось преобразовать из "группы методов" в "Action <string>", как можно это исправить?
[spoiler title="Код"]public void FileRemover(string Location, string Ext) { try { string[] Files; Files = Directory.GetFiles($"{Location}", $"{Ext}", SearchOption.AllDirectories); foreach (string s in Files) { FileInfo file = new FileInfo(s); long FileSize = file.Length; try { File.Delete(s); RemovedSize += FileSize; } catch { } } } catch { } } private void ExUpKeybButton_Click(object sender, EventArgs e) { await Task.Run(() => { new List<string> { LocalApp + @"\Yandex", "*.ldb", LocalApp + @"\Yandex", "*.old", AllUsers + @"\Yandex", "*.log", }.AsParallel().ForAll(FileRemover); Invoke(new Action(Converter)); }); }
[/spoiler]
Спасибо, все работает, только не могу понять, почему когда я добавляю такой код, в "AsParallel", красным подчёркивает "FileRemover", с ошибкой: "Аргумент 2: не удалось преобразовать из "группы методов" в "Action <string>", как можно это исправить?
public void FileRemover(string Location, string Ext)
{
try
{
string[] Files;
Files = Directory.GetFiles($"{Location}", $"{Ext}", SearchOption.AllDirectories);
foreach (string s in Files)
{
FileInfo file = new FileInfo(s);
long FileSize = file.Length;
try
{
File.Delete(s);
RemovedSize += FileSize;
}
catch { }
}
}
catch { }
}
private void ExUpKeybButton_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
new List<string>
{
LocalApp + @"\Yandex", "*.ldb",
LocalApp + @"\Yandex", "*.old",
AllUsers + @"\Yandex", "*.log",
}.AsParallel().ForAll(FileRemover);
Invoke(new Action(Converter));
});
}
Цитата: Adler от 14.04.2021, 14:25Добрый день, @g2o2.
Что-то я не пойму, как вы хотите, что бы это работало?
1.FileRemover(string Location, string Ext)принимает два параметра.
2..AsParallel().ForAll(FileRemover);это вообще что? Тут должно быть что-то вроде.ForAll(x => FileRemover(x, <какой то второй параметр>));
Добрый день, @g2o2.
Что-то я не пойму, как вы хотите, что бы это работало?
1. СкопированоFileRemover(string Location, string Ext) принимает два параметра.
2. Скопировано.AsParallel().ForAll(FileRemover); это вообще что? Тут должно быть что-то вроде Скопировано.ForAll(x => FileRemover(x, <какой то второй параметр>));
Цитата: Владимир от 14.04.2021, 14:48Я хочу по нажатию на кнопку: обратиться к методу "FolderRemover", передать ему путь (к нему получилось обратиться), потом нужно обратиться к методу "FileRemover", передать ему путь и расширение, тут у меня проблема, не понимаю как передать 2 значения, после окончания работы "FolderRemover" и "FileRemover", вызвать "Converter".
Я хочу по нажатию на кнопку: обратиться к методу "FolderRemover", передать ему путь (к нему получилось обратиться), потом нужно обратиться к методу "FileRemover", передать ему путь и расширение, тут у меня проблема, не понимаю как передать 2 значения, после окончания работы "FolderRemover" и "FileRemover", вызвать "Converter".
Цитата: Вася от 14.04.2021, 14:50Если правильно понял задумку, то как-то так:
new List<(string, string)> { (LocalApp + @"\Yandex", "*.ldb"), (LocalApp + @"\Yandex", "*.old"), (AllUsers + @"\Yandex", "*.log"), }.AsParallel().ForAll(x => FileRemover(x.Item1, x.Item2));
Если правильно понял задумку, то как-то так:
new List<(string, string)>
{
(LocalApp + @"\Yandex", "*.ldb"),
(LocalApp + @"\Yandex", "*.old"),
(AllUsers + @"\Yandex", "*.log"),
}.AsParallel().ForAll(x => FileRemover(x.Item1, x.Item2));
Цитата: Владимир от 14.04.2021, 15:07Да, всё верно. Спасибо всем за помощь, вопрос решён.
Да, всё верно. Спасибо всем за помощь, вопрос решён.