Notatka
Dostęp do tej strony wymaga autoryzacji. Może spróbować zalogować się lub zmienić katalogi.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
W aplikacji Zestaw SDK do aplikacji systemu Windows klasycznej proces będzie kontynuowany do momentu jawnego zamknięcia go przez użytkownika. Aplikacje klasyczne nie przechodzą przez automatyczne wstrzymanie, wznowienie i zakończenie cyklu życia używanego przez aplikacje platformy UWP. Zapewnia to większą kontrolę, ale także większą odpowiedzialność za zarządzanie stanem.
Wymagania wstępne
- Projekt aplikacji klasycznej w technologii Zestaw SDK do aplikacji systemu Windows. Aby uzyskać instrukcje konfiguracji, zobacz Tworzenie pierwszej aplikacji WinUI 3.
- Znajomość klasy
Microsoft.UI.Windowing.AppWindoworaz, w przypadku aplikacji spakietowanych,Windows.Storage.ApplicationData.
Ważna
Aplikacje klasyczne oparte na Zestaw SDK do aplikacji systemu Windows nie przechodzą automatycznie w stan zawieszenia i nie są automatycznie wznawiane, jak aplikacje UWP. Aplikacja działa w sposób ciągły, dopóki użytkownik lub system go nie zamknie. Należy nadal implementować dobre rozwiązania w zakresie zarządzania stanami, aby obsługiwać nieoczekiwane zamknięcia, ponowne uruchomienia systemu i utratę zasilania.
Dlaczego zarządzanie stanem ma znaczenie
Mimo że aplikacje klasyczne nie są zawieszone przez system operacyjny, nadal istnieją sytuacje, w których aplikacja może utracić niezapisany stan:
- Użytkownik zamyka aplikację, gdy praca jest w toku
- System uruchamia się ponownie na potrzeby aktualizacji
- Utrata zasilania lub awaria kończy proces
- Użytkownik wyloguje się z Windows
Zaprojektuj aplikację tak, aby obsługiwała te przypadki bezpiecznie, zapisując często ważny stan i przywracając go po uruchomieniu aplikacji.
Przyrostowe zapisywanie stanu
Zamiast zapisywać cały stan przy zamykaniu, zapisz stan przyrostowo, gdy użytkownik działa. Zmniejsza to ryzyko utraty danych i dystrybuuje koszt operacji we/wy w całym okresie istnienia aplikacji.
private async void OnThemeChanged(object sender, SelectionChangedEventArgs e)
{
var selectedTheme = (sender as ComboBox)?.SelectedItem?.ToString();
if (selectedTheme != null)
{
await SaveSettingAsync("AppTheme", selectedTheme);
}
}
private async Task SaveSettingAsync(string key, string value)
{
// Use local file storage, a database, or ApplicationData for packaged apps.
var localFolder = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
var settingsDir = System.IO.Path.Combine(localFolder, "MyApp");
Directory.CreateDirectory(settingsDir);
var settingsPath = System.IO.Path.Combine(settingsDir, "settings.json");
// Read existing settings, update, and save asynchronously.
var settings = LoadSettings(settingsPath);
settings[key] = value;
await File.WriteAllTextAsync(settingsPath, System.Text.Json.JsonSerializer.Serialize(settings));
}
private Dictionary<string, string> LoadSettings(string path)
{
// Read and deserialize the settings file, or return an empty set if it doesn't exist yet.
if (!File.Exists(path))
{
return new Dictionary<string, string>();
}
var json = File.ReadAllText(path);
return System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, string>>(json)
?? new Dictionary<string, string>();
}
Używanie usługi ApplicationData dla spakowanych aplikacji
Jeśli aplikacja jest spakowana przy użyciu pliku MSIX, możesz użyć Windows.Storage.ApplicationData.Current.LocalSettings do przechowywania małych ustawień i LocalFolder większych danych. Te lokalizacje są zarządzane przez system i czyszczone po odinstalowaniu aplikacji.
Note
ApplicationData.Current wymaga identyfikatora pakietu. Jeśli aplikacja jest bez pakietu, użyj Environment.SpecialFolder.LocalApplicationData lub innej standardowej lokalizacji plików.
// For packaged apps with package identity:
string filePath = "C:\\Users\\Example\\Documents\\report.docx";
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
localSettings.Values["LastOpenedFile"] = filePath;
Przywróć stan przy uruchamianiu
Po uruchomieniu aplikacji sprawdź wcześniej zapisany stan i przywróć go. Zapewnia to użytkownikowi płynne korzystanie — może kontynuować od miejsca, w którym skończył.
private void MainWindow_Loaded(object sender, RoutedEventArgs e)
{
// Restore the last opened file, if any.
var localSettings = Windows.Storage.ApplicationData.Current.LocalSettings;
if (localSettings.Values.TryGetValue("LastOpenedFile", out var path))
{
OpenFile(path.ToString());
}
}
private void OpenFile(string path)
{
// Load the document at the given path and update the UI.
}
Obsługa zdarzenia AppWindow.Closing
Użyj zdarzenia Closing w obiekcie Microsoft.UI.Windowing.AppWindow, aby zapisać krytyczny stan przed zakończeniem działania aplikacji. To ostatnia możliwość zachowania stanu, zanim użytkownik zamknie okno.
Ważna
W WinUI 3 zdarzenie Window.Closed nie obsługuje anulowania. Aby wyświetlić użytkownikowi monit przed zamknięciem (na przykład w celu zapisania niezapisanych zmian), zamiast tego użyj zdarzenia Microsoft.UI.Windowing.AppWindow.Closing, które udostępnia obiekt AppWindowClosingEventArgs z właściwością Cancel.
// In your Window constructor or initialization code:
var appWindow = this.AppWindow;
appWindow.Closing += AppWindow_Closing;
void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
{
// See the following examples for what to do here.
}
private void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
{
SaveCurrentDocument();
SaveWindowPosition();
}
private void SaveCurrentDocument()
{
// Persist the current document to disk.
}
private void SaveWindowPosition()
{
// Persist the window's current size and position.
}
Aby monitować użytkownika przed zamknięciem, ustaw ustawienie args.Cancel = true , aby zapobiec zamykaniu okna, a następnie zamknij go programowo po potwierdzeniu przez użytkownika. Użyj flagi straży, aby zapobiec ponownej rejestracji, ponieważ wywołanie this.Close() ponownie wyzwala Closing zdarzenie:
private bool _isClosing = false;
private bool HasUnsavedChanges { get; set; }
private async void AppWindow_Closing(AppWindow sender, AppWindowClosingEventArgs args)
{
if (_isClosing) return;
if (HasUnsavedChanges)
{
args.Cancel = true; // Prevent the window from closing.
// ShowSaveDialog returns true if the user chose to save.
var shouldSave = await ShowSaveDialog();
if (shouldSave)
{
await SaveCurrentDocumentAsync();
}
// Set the guard flag before closing to prevent re-entrancy.
_isClosing = true;
this.Close();
}
}
private Task<bool> ShowSaveDialog()
{
// Prompt the user to save, discard, or cancel.
return Task.FromResult(true);
}
private Task SaveCurrentDocumentAsync()
{
// Persist the current document to disk asynchronously.
return Task.CompletedTask;
}
Najlepsze praktyki
| Practice | Guidance |
|---|---|
| Zapisuj często | Nie czekaj na zamknięcie — zapisz stan, gdy użytkownik działa |
| Użyj asynchronicznego we/wy | Użyj polecenia FileStream lub useAsync: trueFile.WriteAllTextAsync, aby uniknąć blokowania interfejsu użytkownika |
| Minimalizuj rozmiar stanu | Zapisz tylko dane potrzebne do przywrócenia pozycji użytkownika |
| Obsługa zdarzeń zasilania | Nasłuchuj PowerManager.EnergySaverStatusChanged, aby dostosować działanie |
| Przetestuj nieoczekiwane zamknięcia | Użyj Menedżera zadań, aby zakończyć działanie aplikacji i zweryfikować odzyskiwanie stanu |