Вопрос

Я держусь подальше от применения. Я давно предпочел выполнять фоновую работу в Application. Но, для длительных задач, приемлемо ли запускать операции в Application.idle с петлей Doevents?

class LongRunningTask : IDisposable {

    public LongRunningTask(IEnumerable<Tidbit> listOfDataToBeProcessed) {
       Application.Idle += OnIdle;

        foreach(Tidbit t in listofDataToBeProcessed) {
            tidbits.Enqueue(t);
        }
    }

    // Small pieces of data to process
    Queue<Tidbit> tidbits = new Queue<Tidbit>();

    void OnIdle(object sender, EventArgs e) {
        while(tidbits.Count > 0) {
            var tidbit = tasks.Dequeue();
            tidbit.Process();
            // Process any messages that have queued up
            // while the data was being processed
            Application.DoEvents();
        }
    }

    public void Dispose() {
        Application.Idle -= OnIdle;
    }
}

Логика здесь заключается в том, что в событии Application.idle, где мы называем Doevents, нет никаких очередей над сообщениями, поэтому мы не должны иметь возможность повторно въехать в код. Каждый кусочек будет обработан достаточно быстро, чтобы он не должен значительно удерживать очередь сообщений (или пользовательского интерфейса).

Итак, есть ли какой -либо вред или недостаток этого подхода? А именно, безопасно ли звонить DOEVENTS в мероприятии на холостом ходу? Я знаю, что C# 5 будет иметь функцию для решения этой ситуации, но для тех из нас, кто не использует C# 5 (который является большинством из нас на данный момент) и из -за общего любопытства, это хороший план? Или есть более простая альтернатива обработке сообщений во время длительной операции, не прибегая к многопоточному чтению?

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

Это было полезно?

Решение

То, что вы здесь делаете, очень похоже Кооперативная многозадачность. Отказ Это интересная идея, но я бы сказал, что вы действительно должны использовать мульти -потоки для чего -то подобного. .NE Task.Factory.StartNew() И библиотеки TPL, которые действительно облегчают это.

Я бы посоветовал против этого.

Чтобы быть ясным, хотя: у меня нет четкой причины против этого. Как и во многих областях, касающихся программирования: если оно работает, это работает. Тем не менее, вы смешиваете вещи, которые не следует смешивать вместе, в частности, фоновые задачи и задачи пользовательского интерфейса. Я полагаю, что когда вы разделяете фоновые задачи и начинаете Go Fenthy Dinling с помощью многопоточных потоков, пулов потоков, фоновых задач и TPL, вы быстро увидите, что он работает и облегчает жизнь в долгосрочной перспективе.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top