Есть ли какие-либо недостатки в вызове логического кода из Dispose в Blazor?

#c# #blazor #blazor-server-side

Вопрос:

Немного предыстории

Например, предположим, что существует страница Blazor, которая отслеживает, когда человек просматривает страницу, и обновляет DateTime значение, чтобы узнать, когда страница просматривалась в последний раз.

Я хочу отслеживать, когда эти пользователи покидают страницу, и обновлять значение последнего просмотра до момента, когда пользователь уходит, а не когда пользователь впервые присоединяется.

Из того, что я видел, я мог бы что-то сделать, используя NavigationManager содержащиеся в нем события и события, чтобы отслеживать изменения URL-адреса и знать, что пользователь покинул страницу на основе этого, но это кажется чрезмерно сложным, когда кажется, что есть более простое решение.

вопрос

Если у меня есть страница Blazor, которая реализует IDisposable аналогично следующему:

 public partial class RazorPage : IDisposable
{
    private bool disposedValue;

    // ...

    protected virtual void Dispose(bool disposing)
    {
        if (!disposedValue)
        {
            if (disposing)
            {
                TriggerNotificationUpdate();
            }

            disposedValue = true;
        }
    }

    public void Dispose()
    {
        // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
        Dispose(disposing: true);
        GC.SuppressFinalize(this);
    }

    private TriggerNotificationUpdate()
    {
        // ...
    }
}
 

И где TriggerNotificationUpdate() вызывает службу с областью действия, в которую была введена инъекция зависимостей следующим образом:

 private TriggerNotificationUpdate()
{
    _ = Task.Run(async () => {
        await _service.UpdateTimestamp();
    });
}
 

Есть ли какие-либо недостатки или основные причины, по которым я не должен использовать этот тип логики в своем коде?

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

1. Да, довольно плохая идея. Dispose никогда не следует создавать исключение и должно выполняться почти мгновенно, потому что иногда его можно запускать из потока финализатора

2. Iirc, используя Task.Run(async () => { ... }); (а не сохраняя задачу в переменной), проглотит исключения и завершится очень быстро, так как он не ожидает выполнения какого-либо кода. Это технически соответствует вашим требованиям @Charlieface — но я предполагаю, что это все еще плохая идея 🙂

3. Хм, ты прав, не понял, что это было Task.Run . Но я бы все равно сделал try { await _service.UpdateTimestamp(); } catch { } это, потому что это более явно

4. Сделаю, спасибо за комментарии.

5. Функция SuppressFinalize() не вызывается, здесь нет деструктора, и вы можете вмешаться в работу базового класса.