Как постараться не пропускать дескрипторы при вызове в UI от Системы. Поточная обработка. Таймер?

Походит на причины лени len для создания преобразователя:

len [1..100000] 0
-> len [2..100000] (0+1)
-> len [3..100000] (0+1+1)

и так далее. Необходимо вынудить len уменьшить l каждый раз:

len (x:xs) l = l `seq` len xs (l+1)

Для получения дополнительной информации, посмотрите http://haskell.org/haskellwiki/Stack_overflow .

8
задан Davy8 21 October 2009 в 19:39
поделиться

4 ответа

Invoke действует как BeginInvoke / EndInvoke в том смысле, что она отправляет сообщение в поток пользовательского интерфейса, создает дескриптор и ожидает на этом дескрипторе, чтобы определить, когда метод Invoked завершен. Именно эта ручка «протекает». Вы можете видеть, что это безымянные события, используя Process Explorer для отслеживания дескрипторов во время работы приложения.

Если IASyncResult был IDisposable, удаление объекта позаботится об очистке дескриптора. На самом деле дескрипторы очищаются, когда сборщик мусора запускается и вызывает финализатор объекта IASyncResult. Вы можете увидеть это, добавив GC. Collect () после каждых 20 вызовов DoStuff - счетчик дескрипторов падает каждые 20 секунд. Конечно, «решение» проблемы путем добавления вызовов к GC.Collect () - это неправильный способ решения проблемы; пусть сборщик мусора выполняет свою работу.

Если вам не нужен вызов Invoke для синхронизации, используйте BeginInvoke вместо Invoke и не вызывайте EndInvoke; конечный результат будет делать то же самое, но никакие дескрипторы не будут созданы или «просочились».

6
ответ дан 5 December 2019 в 17:38
поделиться

Есть ли причина, по которой вы не можете использовать здесь System.Windows.Forms.Timer? Если таймер привязан к этой форме, вам даже не нужно будет ее вызывать.

2
ответ дан 5 December 2019 в 17:38
поделиться

Интересно - это не ответ, но, основываясь на комментариях Андрея, я бы подумал, что это не приведет к утечкам дескрипторов таким же образом, но это будет происходить с той же скоростью, что и упомянутый OP.

System.Threading.Timer timer;
    public Form2()
    {
        InitializeComponent();

    }

    private void UpdateFormTextCallback()
    {
        this.Text = "Hello World!";
    }

    private Action UpdateFormText;

    private void DoStuff(object value)
    {
        this.Invoke(UpdateFormText);
    }

    protected override void OnLoad(EventArgs e)
    {
        base.OnLoad(e);
        timer = new System.Threading.Timer(new TimerCallback(DoStuff), null, 0, 500);
        UpdateFormText = new Action(UpdateFormTextCallback);
    }
0
ответ дан 5 December 2019 в 17:38
поделиться

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

Чтобы подтвердить теорию, я вручную вызвал GC.Collect () для каждого обратного вызова (не делайте этого в реальных проектах это было просто для проверки, там есть множество статей о том, почему это плохая идея) и счетчик дескрипторов был стабильным.

2
ответ дан 5 December 2019 в 17:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: