Hi there,
I am using C# and UWP to create a Windows store application.
In simple terms, the overall architecture is : View -> Controller -> (Database and BackgroundTask), every name represents a different module in the solution.
BackgroundTask is a WRC module and it registers a task that runs every 15 minutes using a time trigger and if there's a need, it'll update the database.
So if there are changes in the database and if the application is in foreground, i need to update the UI. After doing some research, i found that i need to use something called a Dispatcher as the backgroundTask and main UI Thread are using different memories and are not allowed to communicate with each other.
Now the problem is: ** Dispatcher is only available in View module and i need it in BackgroundTask module. Even if i pass in a reference by injecting an interface or something, when the time-trigger is gonna run the task, it'll start anew, meaning the starting point will be a class in the BackgroundTask (that implements IBackgroundTask interface) and hence, **that instance of Task will not have the reference to the Dispatcher that i provided (as it'll be in the main UI thread).
Also, note that i cannot give direct reference of View to BackgroundTask as C# doesn't allow Cyclic Dependency.
I've been thinking about this for over a week now but couldn't find a solution.
Any help would be appreciated.
Thank you.
Edit:
this is how i'm registering the task:
private readonly string EntryPoint = typeof(BackgroundTaskEntryPoint).FullName;
internal async void Register()
{
if (!IsAlreadyRegistered(TaskName))
{
BackgroundTaskBuilder TaskBuilder = new BackgroundTaskBuilder
{
Name = TaskName,
TaskEntryPoint = EntryPoint
};
TaskBuilder.SetTrigger(BackgroundTaskTrigger);
BackgroundAccessStatus status = await BackgroundExecutionManager.RequestAccessAsync();
if (status == BackgroundAccessStatus.DeniedBySystemPolicy ||
status == BackgroundAccessStatus.DeniedByUser)
{
return;
}
var task = TaskBuilder.Register();
task.Completed += new BackgroundTaskCompletedEventHandler(Task_Completed);
}
}
private void Task_Completed(BackgroundTaskRegistration sender, BackgroundTaskCompletedEventArgs args)
{
Debug.WriteLine("Task Completed event was raised");
}
the trigger in this case is : [ToastNotificationHistoryChangedTrigger][1] and is being referred to as TOAST_STATUS_CHANGER in the following code snippet.
and this is the entry point:
public sealed class BackgroundTaskEntryPoint : IBackgroundTask
{
private BackgroundTaskDeferral deferral;
private readonly string QUARTER_HOUR_TOAST_SCHEDULER =
typeof(QuarterHourToastSchedulerBackgroundProcessRegistrar).Name;
private readonly string USER_PRESENT_TOAST_SCHEDULER =
typeof(UserPresentToastSchedulerBackgroundProcessRegistrar).Name;
private readonly string TOAST_INTERACTION_HANDLER =
typeof(ToastInteractionHandlerBackgroundProcessRegistrar).Name;
private readonly string TOAST_STATUS_CHANGER =
typeof(ToastNotificationDisplayedStatusChangerBackgroundProcessRegistrar).Name;
public void Run(IBackgroundTaskInstance taskInstance)
{
deferral = taskInstance.GetDeferral();
string taskName = taskInstance.Task.Name;
if (taskName.Equals(QUARTER_HOUR_TOAST_SCHEDULER))
{
new ReminderToastScheduler().Schedule();
}
else if (taskName.Equals(USER_PRESENT_TOAST_SCHEDULER))
{
new MissedReminderToastScheduler().Schedule();
new ReminderToastScheduler().Schedule();
}
else if (taskName.Equals(TOAST_INTERACTION_HANDLER))
{
new ToastInteractionHandler(
taskInstance.TriggerDetails as ToastNotificationActionTriggerDetail
)
.HandleInteraction();
}
else if (taskName.Equals(TOAST_STATUS_CHANGER))
{
new ReminderStatusChanger().ChangeStatusToDisplayed();
}
deferral.Complete();
}
}
and this is the ReminderStatusChanger class:
internal class ReminderStatusChanger
{
private SQLiteDatabase databaseInstance;
internal ReminderStatusChanger()
{
databaseInstance = SQLiteDatabase.GetInstance();
}
internal void ChangeStatusToDisplayed()
{
foreach (var toast in ToastNotificationManager.History.GetHistory())
{
try
{
databaseInstance.UpdateStatusToDisplayed(toast.Tag);
}
catch (Exception) { }
}
}
}