Задержка отправки вызова? - PullRequest
       3

Задержка отправки вызова?

16 голосов
/ 18 сентября 2010

В WPF из-за сложностей с обновлением интерфейса мне иногда приходится выполнять действия после небольшой задержки.

В настоящее время я делаю это просто:

        var dt = new DispatcherTimer(DispatcherPriority.Send);
        dt.Tick += (s, e) =>
        {
            dt.Stop();
            //DoStuff
        };
        dt.Interval = TimeSpan.FromMilliseconds(200);
        dt.Start();

Но это немного уродливо и, возможно, слишком накладные расходы, чтобы каждый раз создавать новый таймер (?) Что лучше отпроизводительность, чтобы сделать это, то есть выполнить наиболее быстро?И какой хороший способ переписать приведенный выше код в нечто вроде:

        this.Dispatcher.BeginInvoke(new Action(delegate()
        {
            //DoStuff
        }), DispatcherPriority.Send,TimeSpan.FromMilliseconds(200));

Где Timespan - задержка, Спасибо за любой ввод:)

Ответы [ 4 ]

12 голосов
/ 18 сентября 2010

Я бы не предположил , что DispatcherTimer имеет большой вес ... почему бы просто не написать метод расширения для Dispatcher, который позволяет вам использовать нужный синтаксис, и использует DispatcherTimer на заднем плане? Я лично назвал бы это DelayInvoke, а не BeginInvoke, хотя ... и я бы также исправил это, чтобы всегда использовать Action, а не произвольный делегат ..., который облегчит использование лямбда-выражений:

Dispatcher.DelayInvoke(TimeSpan.FromMilliseconds(200), () => { ... 
});

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

Учитывая, что вы, скорее всего, будете чаще использовать миллисекунды, у вас может быть и другой вспомогательный метод:

Dispatcher.DelayInvokeMillis(200, () => { ... 
});

Другая альтернатива - просто использовать существующий метод BeginInvoke, но с очень низким приоритетом, поэтому ваш делегат будет вызываться только после того, как все остальное закончится. Не зная деталей вашей ситуации, трудно понять, сработает ли это или нет, но стоит попробовать.

6 голосов
/ 05 августа 2014

A .NET 4.5 way:

    public async void MyMethod()
    {
        await Task.Delay(20); 
        await Dispatcher.BeginInvoke((Action)DoStuff);
    }
1 голос
/ 22 февраля 2017

Мне не нравится DispatcherTimer, потому что нет простого способа передачи параметров, кроме как через область действия / замыкания функции.

Вместо этого я использую Task.Delay() и оборачиваю это в Dispatcher.Delay() метод расширения:

public static class DispatcherExtensions
{

    public static void Delay(this Dispatcher disp, int delayMs,
                             Action<object> action, object parm = null)
    {
        var ignore = Task.Delay(delayMs).ContinueWith((t) =>
        {
            disp.Invoke(action, parm);
        });
    }

    public static void DelayWithPriority(this Dispatcher disp, int delayMs,
                      Action<object> action, object parm = null, 
                      DispatcherPriority priority = DispatcherPriority.ApplicationIdle)
    {
        var ignore = Task.Delay(delayMs).ContinueWith((t) =>
        {
            disp.BeginInvoke(action, priority, parm);
        });

    }

    public static async Task DelayAsync(this Dispatcher disp, int delayMs,
                      Action<object> action, object parm = null,
                      DispatcherPriority priority = DispatcherPriority.ApplicationIdle)
    {
        await Task.Delay(delayMs);
        await disp.BeginInvoke(action, priority, parm);
    }
}

Чтобы позвонить тогда:

Dispatcher.Delay(4000, (win) =>
{
     var window = win as MainWindow;
     window.ShowStatus(null, 0);
},this);
0 голосов
/ 19 сентября 2010

Вы можете использовать класс DelayBinding Пола Стоуэлла отсюда: http://www.paulstovell.com/wpf-delaybinding.

С этим можно связать DeperdencyProperty с классом, который может выполнять действие при изменении свойства.Привязка будет управлять задержкой.Может быть особенно хорошо, если у вас есть дизайн типа MVVM.

...