Blazored (функция async void) — программа выходит из функции перед созданием каталога

#c# #async-await #task #blazor

#c# #async-ожидание #задача #blazor

Вопрос:

У меня проблема с асинхронной функцией в моем веб-интерфейсе, которую довольно сложно решить.

Я использую функцию входа в систему для своей программы, где данные входа / сеанса обрабатываются внутри myLocalStore-Object .

Этот объект инициализируется / «вводится» в начале страницы входа в систему:

 @inject Blazored.LocalStorage.ILocalStorageService myLocalStore
 

Далее, у меня есть функция входа в систему, которая выполняет две вещи:

  1. Создайте каталог для пользовательских данных (изображений, файлов .csv и т. Д.)
  2. Сохраните данные, связанные с сеансом (имя пользователя, путь к сеансу, ExpertMode и т. Д.)

Теперь я хочу сначала создать свой каталог, а затем сохранить данные сеанса:

 public async void SaveSession()
{
    ClearSession();
    
    Message = "Session Saved";
    
    string SessionPathRel = "_"   Login.Name   "/";
    
    string SessionPathAbs = Directory.GetCurrentDirectory();
    SessionPathAbs = SessionPathAbs   @"wwwroot"   "_"   Login.Name   @"";
    
    //CREATE DIRECTORY
    Directory.CreateDirectory(SessionPathAbs);
    
    //SAVE SESSION DATA
    await myLocalStore.SetItemAsync("UserLoginName", Login.Name);        
    await myLocalStore.SetItemAsync("SessionPathAbs", SessionPathAbs);
    await myLocalStore.SetItemAsync("SessionPathRel", SessionPathRel); 
    await myLocalStore.SetItemAsync("isLogged", true);
 

Проблема сейчас в том, что программа запущена, она пропускает / перепрыгивает через «Каталог.Строка «CreateDirectory» и завершает функцию без создания каталога. Когда я использую точку останова в соответствующей строке, все работает правильно.

Мы уже предприняли несколько попыток (используя sync вместо асинхронных функций, возвращая Task<Blazored .localStorage.ILocalStorageService> вместо void для SaveSession), но все это не сработало. Кто-нибудь знает решение этой проблемы?

Редактировать:

исправлено с помощью Task.Run() — command . Просто вставьте код в качестве примера здесь:

     public async Task SaveSession()
    {
        await ClearSession();
    
        Message = "Session Saved";
    
        string SessionPathRel = "_"   Login.Name   "/";
    
        string SessionPathAbs = Directory.GetCurrentDirectory();
        SessionPathAbs = SessionPathAbs   @"wwwroot"   "_"   Login.Name   @"";
    
        //CREATE DIRECTORY
        await Task.Run(() => Directory.CreateDirectory(SessionPathAbs));
    
        //SAVE SESSION DATA
        await myLocalStore.SetItemAsync("UserLoginName",    Login.Name);        
        await myLocalStore.SetItemAsync("SessionPathAbs",   SessionPathAbs);
        await myLocalStore.SetItemAsync("SessionPathRel",   SessionPathRel); 
        await myLocalStore.SetItemAsync("isLogged",         true);
        //GlobalConfiguration.URL_Handler.updateURLWithSubname(Login.Name);
    
        NavigationManager.NavigateTo(URL_Handler.DashboardURL, true);
    }
    
    public async Task ClearSession()
    {
    try{
       string SessionPathAbs   = await myLocalStore.GetItemAsync<string>("SessionPathAbs");
       System.IO.DirectoryInfo SessionDirectoryAbs = new DirectoryInfo(SessionPathAbs);
    
       await Task.Run(() => SessionDirectoryAbs.Delete(true));
            //SessionDirectoryAbs.Delete(true);
     }
     catch
     {
         
     }
    
     GlobalConfiguration.URL_Handler.clearURLWithSubname();
    
     Message = "Session is clear";
     SessionValue = "";
    
     await myLocalStore.ClearAsync();
    
 }
 

Комментарии:

1. Избегайте async void . Он предназначен для обработчиков событий. Используйте async Task вместо этого.

2. Пробовал, но я думаю, что есть еще одна проблема, которая заключается в следующем: у меня дополнительно есть ClearSession()- функция, которая вызывается «перед» сеансом сохранения, но фактически выполняется после. Итак, программа создала каталог и впоследствии очищает каталог, хотя ClearSession() вызывается ранее. (Думаю, это какая-то проблема с организацией порядка выполнения для асинхронных методов. Есть ли какой-либо способ, которым я могу «принудительно» очистить сеанс для выполнения, даже если метод является «Асинхронной задачей»?

3. Кто вызывает SaveSession и где он вызывается? Веб-сборка или сервер? Directory.CreateDirectory не будет работать в браузере, поскольку у вас нет доступа к локальной файловой системе.

4. Согласен с MrC — но кроме того, вы не «исправили это», вы просто проглотили ошибку. Кроме того, я не думаю, что вы хотите хранить информацию в браузере таким образом — действительно плохая идея хранить имя пользователя и путь к тому, что потенциально является каталогом на сервере таким образом. Кому-то не составит труда изменить имя пользователя в хранилище своего браузера и, возможно, прочитать или очистить данные сеанса другого пользователя

5. спасибо за отзыв, ну, у меня не так много опыта в разработке веб-интерфейсов. у вас есть надежная ссылка на то, как это реализовать чисто? Я использую сервер blazor.