События
Присоединение к вызову ИИ Навыков
8 апр., 15 - 28 мая, 07
Отточите свои навыки ИИ и введите подметки, чтобы выиграть бесплатный экзамен сертификации
Зарегистрируйтесь!Этот браузер больше не поддерживается.
Выполните обновление до Microsoft Edge, чтобы воспользоваться новейшими функциями, обновлениями для системы безопасности и технической поддержкой.
Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Важные API
Создайте класс фоновой задачи и зарегистрируйте его для запуска, если приложение не находится на переднем плане. В этом разделе показано, как создать и зарегистрировать фоновую задачу, которая выполняется в отдельном процессе, чем процесс приложения. Чтобы выполнить фоновую работу непосредственно в приложении переднего плана, см. статью "Создание и регистрация фоновой задачи в процессе".
Примечание
Если вы используете фоновую задачу для воспроизведения мультимедиа в фоновом режиме, ознакомьтесь со сведениями об улучшениях в Windows 10 версии 1607, что значительно упрощает воспроизведение мультимедиа.
Примечание
Если вы реализуете внепроцессную фоновую задачу в классическом приложении C# с .NET 6 или более поздней версии, используйте поддержку разработки C#/WinRT для создания компонента среда выполнения Windows. Это относится к приложениям с помощью пакета SDK для приложений Windows, WinUI 3, WPF или WinForms. Пример фоновой задачи см. в примере.
Вы можете запустить код в фоновом режиме, написав классы, реализующие интерфейс IBackgroundTask . Этот код запускается при активации определенного события, например SystemTrigger или MaintenanceTrigger.
Ниже показано, как написать новый класс, реализующий интерфейс IBackgroundTask .
Примечание
Сам класс фоновой задачи (и все остальные классы в проекте фоновой задачи) должны быть общедоступными классами, которые запечатаны (или окончательные).
В следующем примере кода показана очень базовая отправная точка для класса фоновой задачи.
// ExampleBackgroundTask.cs
using Windows.ApplicationModel.Background;
namespace Tasks
{
public sealed class ExampleBackgroundTask : IBackgroundTask
{
public void Run(IBackgroundTaskInstance taskInstance)
{
}
}
}
// First, add ExampleBackgroundTask.idl, and then build.
// ExampleBackgroundTask.idl
namespace Tasks
{
[default_interface]
runtimeclass ExampleBackgroundTask : Windows.ApplicationModel.Background.IBackgroundTask
{
ExampleBackgroundTask();
}
}
// ExampleBackgroundTask.h
#pragma once
#include "ExampleBackgroundTask.g.h"
namespace winrt::Tasks::implementation
{
struct ExampleBackgroundTask : ExampleBackgroundTaskT<ExampleBackgroundTask>
{
ExampleBackgroundTask() = default;
void Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance);
};
}
namespace winrt::Tasks::factory_implementation
{
struct ExampleBackgroundTask : ExampleBackgroundTaskT<ExampleBackgroundTask, implementation::ExampleBackgroundTask>
{
};
}
// ExampleBackgroundTask.cpp
#include "pch.h"
#include "ExampleBackgroundTask.h"
namespace winrt::Tasks::implementation
{
void ExampleBackgroundTask::Run(Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance)
{
throw hresult_not_implemented();
}
}
// ExampleBackgroundTask.h
#pragma once
using namespace Windows::ApplicationModel::Background;
namespace Tasks
{
public ref class ExampleBackgroundTask sealed : public IBackgroundTask
{
public:
ExampleBackgroundTask();
virtual void Run(IBackgroundTaskInstance^ taskInstance);
void OnCompleted(
BackgroundTaskRegistration^ task,
BackgroundTaskCompletedEventArgs^ args
);
};
}
// ExampleBackgroundTask.cpp
#include "ExampleBackgroundTask.h"
using namespace Tasks;
void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
}
Запросите отсрочку в методе Run перед вызовом асинхронного метода. Сохраните отсрочку в член данных класса, чтобы получить доступ к нему из асинхронного метода. Объявите отсрочку после завершения асинхронного кода.
Следующий пример кода получает отсрочку, сохраняет его и освобождает его после завершения асинхронного кода.
BackgroundTaskDeferral _deferral; // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation
public async void Run(IBackgroundTaskInstance taskInstance)
{
_deferral = taskInstance.GetDeferral();
//
// TODO: Insert code to start one or more asynchronous methods using the
// await keyword, for example:
//
// await ExampleMethodAsync();
//
_deferral.Complete();
}
// ExampleBackgroundTask.h
...
private:
Windows::ApplicationModel::Background::BackgroundTaskDeferral m_deferral{ nullptr };
// ExampleBackgroundTask.cpp
...
Windows::Foundation::IAsyncAction ExampleBackgroundTask::Run(
Windows::ApplicationModel::Background::IBackgroundTaskInstance const& taskInstance)
{
m_deferral = taskInstance.GetDeferral(); // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation.
// TODO: Modify the following line of code to call a real async function.
co_await ExampleCoroutineAsync(); // Run returns at this point, and resumes when ExampleCoroutineAsync completes.
m_deferral.Complete();
}
void ExampleBackgroundTask::Run(IBackgroundTaskInstance^ taskInstance)
{
m_deferral = taskInstance->GetDeferral(); // Note: defined at class scope so that we can mark it complete inside the OnCancel() callback if we choose to support cancellation.
//
// TODO: Modify the following line of code to call a real async function.
// Note that the task<void> return type applies only to async
// actions. If you need to call an async operation instead, replace
// task<void> with the correct return type.
//
task<void> myTask(ExampleFunctionAsync());
myTask.then([=]() {
m_deferral->Complete();
});
}
Примечание
В C#асинхронные методы фоновой задачи можно вызывать с помощью ключевых слов async/await . В C++/CX аналогичный результат можно достичь с помощью цепочки задач.
Дополнительные сведения об асинхронном программировании см. в статье "Асинхронное программирование". Дополнительные примеры использования отложений для сохранения фоновой задачи от остановки в начале работы см. в примере фоновой задачи.
Следующие действия выполняются в одном из классов приложения (например, MainPage.xaml.cs).
Примечание
Вы также можете создать функцию, выделенную для регистрации фоновых задач, см. раздел "Регистрация фоновой задачи". В этом случае вместо следующих трех шагов можно просто создать триггер и предоставить его функции регистрации вместе с именем задачи, точкой входа задачи и (необязательно) условием.
В следующем примере выполняется итерацию свойства AllTasks и задает для переменной флага значение true, если задача уже зарегистрирована.
var taskRegistered = false;
var exampleTaskName = "ExampleBackgroundTask";
foreach (var task in BackgroundTaskRegistration.AllTasks)
{
if (task.Value.Name == exampleTaskName)
{
taskRegistered = true;
break;
}
}
std::wstring exampleTaskName{ L"ExampleBackgroundTask" };
auto allTasks{ Windows::ApplicationModel::Background::BackgroundTaskRegistration::AllTasks() };
bool taskRegistered{ false };
for (auto const& task : allTasks)
{
if (task.Value().Name() == exampleTaskName)
{
taskRegistered = true;
break;
}
}
// The code in the next step goes here.
boolean taskRegistered = false;
Platform::String^ exampleTaskName = "ExampleBackgroundTask";
auto iter = BackgroundTaskRegistration::AllTasks->First();
auto hascur = iter->HasCurrent;
while (hascur)
{
auto cur = iter->Current->Value;
if(cur->Name == exampleTaskName)
{
taskRegistered = true;
break;
}
hascur = iter->MoveNext();
}
Триггер фоновой задачи управляет выполнением фоновой задачи. Список возможных триггеров см. в разделе SystemTrigger.
Например, этот код создает новую фоновую задачу и задает ее для запуска при возникновении триггера TimeZoneChanged :
var builder = new BackgroundTaskBuilder();
builder.Name = exampleTaskName;
builder.TaskEntryPoint = "Tasks.ExampleBackgroundTask";
builder.SetTrigger(new SystemTrigger(SystemTriggerType.TimeZoneChange, false));
if (!taskRegistered)
{
Windows::ApplicationModel::Background::BackgroundTaskBuilder builder;
builder.Name(exampleTaskName);
builder.TaskEntryPoint(L"Tasks.ExampleBackgroundTask");
builder.SetTrigger(Windows::ApplicationModel::Background::SystemTrigger{
Windows::ApplicationModel::Background::SystemTriggerType::TimeZoneChange, false });
// The code in the next step goes here.
}
auto builder = ref new BackgroundTaskBuilder();
builder->Name = exampleTaskName;
builder->TaskEntryPoint = "Tasks.ExampleBackgroundTask";
builder->SetTrigger(ref new SystemTrigger(SystemTriggerType::TimeZoneChange, false));
В следующем примере кода назначается условие, требующее наличия у пользователя:
builder.AddCondition(new SystemCondition(SystemConditionType.UserPresent));
builder.AddCondition(Windows::ApplicationModel::Background::SystemCondition{ Windows::ApplicationModel::Background::SystemConditionType::UserPresent });
// The code in the next step goes here.
builder->AddCondition(ref new SystemCondition(SystemConditionType::UserPresent));
Следующий код регистрирует фоновую задачу и сохраняет результат:
BackgroundTaskRegistration task = builder.Register();
Windows::ApplicationModel::Background::BackgroundTaskRegistration task{ builder.Register() };
BackgroundTaskRegistration^ task = builder->Register();
Примечание
Универсальные приложения Windows должны вызывать RequestAccessAsync перед регистрацией любого из типов фоновых триггеров.
Чтобы обеспечить правильную работу приложения универсального windows после выпуска обновления, используйте триггер ServiceingComplete (см . SystemTriggerType) для выполнения любых изменений конфигурации после обновления, таких как перенос базы данных приложения и регистрация фоновых задач. Рекомендуется отменить регистрацию фоновых задач, связанных с предыдущей версией приложения (см. раздел RemoveAccess) и зарегистрировать фоновые задачи для новой версии приложения (см. раздел RequestAccessAsync) в настоящее время.
Дополнительные сведения см. в руководстве по фоновым задачам.
Необходимо зарегистрировать метод в BackgroundTaskCompletedEventHandler, чтобы приложение получите результаты из фоновой задачи. Когда приложение запускается или возобновляется, помеченный метод будет вызываться, если фоновая задача завершена с момента последнего запуска приложения на переднем плане. (Метод OnCompleted будет вызываться немедленно, если фоновая задача завершается, пока приложение находится на переднем плане.)
В следующем примере кода распознается завершение фоновой задачи и вызывается пример метода обновления пользовательского интерфейса, который принимает строку сообщения.
private void OnCompleted(IBackgroundTaskRegistration task, BackgroundTaskCompletedEventArgs args)
{
var settings = Windows.Storage.ApplicationData.Current.LocalSettings;
var key = task.TaskId.ToString();
var message = settings.Values[key].ToString();
UpdateUI(message);
}
void UpdateUI(winrt::hstring const& message)
{
MyTextBlock().Dispatcher().RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal, [=]()
{
MyTextBlock().Text(message);
});
}
void OnCompleted(
Windows::ApplicationModel::Background::BackgroundTaskRegistration const& sender,
Windows::ApplicationModel::Background::BackgroundTaskCompletedEventArgs const& /* args */)
{
// You'll previously have inserted this key into local settings.
auto settings{ Windows::Storage::ApplicationData::Current().LocalSettings().Values() };
auto key{ winrt::to_hstring(sender.TaskId()) };
auto message{ winrt::unbox_value<winrt::hstring>(settings.Lookup(key)) };
UpdateUI(message);
}
void MainPage::OnCompleted(BackgroundTaskRegistration^ task, BackgroundTaskCompletedEventArgs^ args)
{
auto settings = ApplicationData::Current->LocalSettings->Values;
auto key = task->TaskId.ToString();
auto message = dynamic_cast<String^>(settings->Lookup(key));
UpdateUI(message);
}
Примечание
Обновления пользовательского интерфейса должны выполняться асинхронно, чтобы избежать удержания потока пользовательского интерфейса. Пример см. в методе UpdateUI в примере фоновой задачи.
Следующий пример кода добавляет BackgroundTaskCompletedEventHandler в BackgroundTaskRegistration:
task.Completed += new BackgroundTaskCompletedEventHandler(OnCompleted);
task.Completed({ this, &MainPage::OnCompleted });
task->Completed += ref new BackgroundTaskCompletedEventHandler(this, &MainPage::OnCompleted);
Прежде чем приложение сможет выполнять фоновые задачи, необходимо объявить каждую фоновую задачу в манифесте приложения. Если приложение пытается зарегистрировать фоновую задачу с триггером, который не указан в манифесте, регистрация фоновой задачи завершится ошибкой "класс среды выполнения не зарегистрирован".
Следующий элемент Extensions добавляется в файл Package.appxmanifest для регистрации фоновой задачи:
<Extensions>
<Extension Category="windows.backgroundTasks" EntryPoint="Tasks.ExampleBackgroundTask">
<BackgroundTasks>
<Task Type="systemEvent" />
</BackgroundTasks>
</Extension>
</Extensions>
Теперь вы должны понять основы написания фонового класса задач, регистрации фоновой задачи из приложения и способа распознавания приложения при завершении фоновой задачи. Вы также должны понять, как обновить манифест приложения, чтобы приложение успешно зарегистрировать фоновую задачу.
Примечание
Скачайте пример фоновой задачи, чтобы просмотреть аналогичные примеры кода в контексте полного и надежного приложения UWP, использующего фоновые задачи.
Дополнительные сведения см. в следующих разделах, посвященных справочнику по API, концептуальной инструкции по фоновой задаче и более подробные инструкции по написанию приложений, использующих фоновые задачи.
Подробные инструкции по фоновым задачам
Руководство по фоновой задаче
Справочник по API фоновой задачи
События
Присоединение к вызову ИИ Навыков
8 апр., 15 - 28 мая, 07
Отточите свои навыки ИИ и введите подметки, чтобы выиграть бесплатный экзамен сертификации
Зарегистрируйтесь!