Как узнать, когда действительно начинается асинхронный вызов?

2

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

Когда я вызываю метод синхронно, я запускаю следующий код и получаю точное количество времени, которое потребовал метод MyMethod.

for (int i = 0; i < 5000; i++) {
    stopWatches[i].Start();
    webService.MyMethod(new Request());
    stopWatches[i].Stop();
}

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

var callback = new Action<IAsyncResult>(ar => {
    int i = (int)ar.AsyncState;

    try {
        var response = webService.EndMyMethod(ar);
        stopWatches[i].Stop();
    }
}

for (int i = 0; i < 5000; i++) {
    webService.BeginMyMethod(new Request(), new AsyncCallback(callback), i);
    stopWatches[i].Start();
}

Проблема заключается в том, что секундомеры не измеряют время, необходимое для выполнения запроса больше. Они измеряют время с момента ввода запроса в очередь ThreadPool до конца вызова. Таким образом, я заканчиваю список секундомеров с линейным увеличением времени.

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

Спасибо!

UPDATE: я не могу изменить реализацию MyMethod.

  • 1
    Почему вы не можете изменить реализацию MyMethod?
Теги:
asynchronous

3 ответа

1
Лучший ответ

Создайте метод BeginTimedMyMethod, а не в классе webservice. В реализации BeginTimedMyMethod вызовите промежуточный метод вместо MyMethod, который вызывается асинхронно. Запустите секундомер там, затем вызовите MyMethod.

void BeginTimedMyMethod(...)
{
    //create delegate with StartMethod as target
    //Invoke StartMethod delegate
}

void StartTimedMethod(Request request)
{
    stopWatches[i].Start();
    webservice.MyMethod(request);
}
0

Что именно вы пытаетесь сделать с измерениями? Как и вы, вы измеряете фактическое количество времени, которое требуется, когда вы просите, чтобы какая-либо работа была выполнена, когда она будет завершена. Кажется, это имеет смысл. Как до, так и после вашего кодового переключателя вы измеряете фактическую задержку запроса.

0

Похоже, что вы пытаетесь настроить аспект вокруг класса mymethod. Самый простой способ сделать это будет с помощью инфраструктуры AOP, такой как PostSharp. Что вы создаете что-то в строках

public class MyStopWatchContext
{
    Stopwatch _watch = new Stopwatch();

    public void OnMethodEntry()
    {
        _watch.Start();
    }

    public void OnMethodExit()
    {
        _watch.End();
        Debug.Print(_watch.Duration);
    }
}

Затем внутри вашего класса с помощью вашего метода вы

public class MyService
{
    [MyStopWatchContext]
    public void SomeServiceMethod()
    { ...
    }
}

Это позволит вам привязать этот аспект к методу без необходимости изменения метода. Однако вам все равно придется перекомпилировать код там. Таким образом, это должно быть жизнеспособным, даже если этот класс является просто прокси-сервером для внешней службы, на которую у вас нет контроля, поскольку вы должны просто сидеть в этом аспекте на прокси-сервере.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню