Вы должны войти, чтобы создавать сообщения и темы.

Как дождаться окончания работы асинхронных методов. [Решено]

Добрый день, есть "клик" по кнопке, который много раз вызывает метод для удаления папок/файлов "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();
});
}


Либо же как можно написать по-другому этот код, рассмотрю все варианты)

Добрый день!
Метод "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));
    });
}

Лайкнул Владимир
Владимир

Спасибо, все работает, только не могу понять, почему когда я добавляю такой код, в "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));
            });  
        }

 

Добрый день, @g2o2.
Что-то я не пойму, как вы хотите, что бы это работало?
1. СкопированоFileRemover(string Location, string Ext) принимает два параметра.
2. Скопировано.AsParallel().ForAll(FileRemover); это вообще что? Тут должно быть что-то вроде Скопировано.ForAll(x => FileRemover(x, <какой то второй параметр>));

Лайкнул Владимир
Владимир

Я хочу по нажатию на кнопку: обратиться к методу "FolderRemover", передать ему путь (к нему получилось обратиться), потом нужно обратиться к методу "FileRemover", передать ему путь и расширение, тут у меня проблема, не понимаю как передать 2 значения, после окончания работы "FolderRemover" и "FileRemover", вызвать "Converter".

Если правильно понял задумку, то как-то так:

new List<(string, string)>
    {
        (LocalApp + @"\Yandex", "*.ldb"),
        (LocalApp + @"\Yandex", "*.old"),
        (AllUsers + @"\Yandex", "*.log"),
    }.AsParallel().ForAll(x => FileRemover(x.Item1, x.Item2));
Лайкнул Владимир
Владимир

Да, всё верно. Спасибо всем за помощь, вопрос решён.