#c# #async-await #task #blazor
#c# #async-ожидание #задача #blazor
Вопрос:
У меня проблема с асинхронной функцией в моем веб-интерфейсе, которую довольно сложно решить.
Я использую функцию входа в систему для своей программы, где данные входа / сеанса обрабатываются внутри myLocalStore-Object
.
Этот объект инициализируется / «вводится» в начале страницы входа в систему:
@inject Blazored.LocalStorage.ILocalStorageService myLocalStore
Далее, у меня есть функция входа в систему, которая выполняет две вещи:
- Создайте каталог для пользовательских данных (изображений, файлов .csv и т. Д.)
- Сохраните данные, связанные с сеансом (имя пользователя, путь к сеансу, 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.