Алгоритмы сообщения о ходе выполнения асинхронных вызовов функций - PullRequest
0 голосов
/ 26 июля 2011

Какие алгоритмы используются для вычисления хода выполнения вызова функции?

Очевидно, что это легко сделать, если у вас есть цикл, что-то вроде:

 Action<Double> notifier = d => Console.WriteLine("Completed: " + d.ToString());

 Double _interval = 0.05;

 for (int i = 0; i < 1000; i++)
            {
                int rem = default(int); 

                Math.DivRem(i, _interval, out rem);

                if (rem == 0)
                {
                    double progress = (double)i / 1000;
                    notifier(progress); 
                }
             }

Но что делать, когда у вас есть какой-то универсальный делегат, и вы хотите запустить его асинхронно, но такжеуведомить другую ветку о ее продвижении, и вы не можете гарантировать, что можете прямо использовать цикл for?Некоторые другие простые способы могут быть следующими:

1) Сначала запрограммируйте функцию (очень плохо для производительности, хотя, если это длительное задание)

2) Сохраните прошлые моменты времени функции в журнале ииспользуйте это (но это не обязательно учитывает дополнительные переменные - процессор, память и т. д. в конкретное время выполнения задачи)

Однако существуют ли какие-либо более продвинутые алгоритмы, даже если они только приближают прогресс?

Ответы [ 3 ]

2 голосов
/ 26 июля 2011

Класс BackgroundWorker имеет функцию обратного вызова обновления, но в ответ на ваш вопрос о «общем алгоритме» для поиска завершения, Не совсем.Самое близкое, что вы можете получить - это оценка на основе длины функции (http://www.ndepend.com/), которая даст вам длину в строках кода.

1 голос
/ 26 июля 2011

Это академический вопрос?

Если нет, вы можете использовать BackgroundWorker со встроенным ReportProgress методом

http://msdn.microsoft.com/en-us/library/ka89zff4.aspx

Полагаю, вы также можете использовать .net рефлектор, чтобы посмотреть на его реализацию, если вам интересно

1 голос
/ 26 июля 2011

Передайте рабочей функции делегата обратного вызова и сообщите о своем прогрессе обратно в пользовательский интерфейс.

Пользовательский интерфейс не должен отвечать за "выяснение того, что делать", вместо этого он должен просто принимать обновленияот работника.

Например:

 void longRunningFunction(Action<int> updateCallback)
 {
        // Do something long, but on measurable places, call updateCallback
        updateCallback(50);
 }

А в интерфейсе:

longRunningFunction(x => progressBar.SetProgress(x));
...