Установка таймера на асинхронный запрос - PullRequest
0 голосов
/ 12 марта 2012

У меня есть функции, которые генерирует wsdl, и одна из них является асинхронной, которая также имеет событие.

ws.GetRequest("Login","Username","Password");
ws.GetRequestCompleted+=delegate(object sender,WS.GetRequestCompletedEventArgs e)
{
   //somecode
}

Я хочу создать таймер для запроса выше, если через некоторое времяGetRequestCompleted не произойдет, я покажу сообщение об ошибке.У меня нет доступа к функции wsdl.

1 Ответ

2 голосов
/ 13 марта 2012

Вам нужно будет сделать две вещи:

  • Запустить таймер при запуске запроса
  • Когда сработает таймер, если обратный вызов не был вызван, броситьисключение

Похоже, что это происходит в методе, и вы используете анонимные методы для подписей делегатов, поэтому я рекомендую использовать замыкания, например:

// Let's say you want to wait for 5 seconds.
System.Timers.Timer t = new System.Timers.Timer(5000);

// Has the timer completed?  The callback on the web service?
bool wsCompleted = false, timerCompleted = false, exceptionThrown = false;

// Need to synchronize access to above, since it will come back on
// different threads.
object l = new object();

// Set up the callback on the timer.
t.Elapsed = delegate(object sender, ElapsedEventArgs e) {
    // Lock access.
    lock (l)
    {
        // Set the flag to true.
        timerCompleted = true;

        // If the web service has not completed and
        // the exception was not thrown, then
        // throw your exception here.
        if (!wsCompleted && !exceptionThrown) 
        {
            // The exception is being thrown.
            exceptionThrown = true;
            throw new Exception();
        }
    }
};

// Set up the callback on the web service.
ws.GetRequestCompleted += 
    delegate(object sender,WS.GetRequestCompletedEventArgs e) {
        // Dispose of timer when done.
        using (t)
        // Lock.
        lock (l)
        {
            // The web service call has completed.
            wsCompleted = true;

            // If the timer completed and the exception was
            // not thrown, then do so here.
            if (timerCompleted && !exceptionThrown)
            {
                // The exception is being thrown.
                exceptionThrown = true;
                throw new Exception();
            }
        }

        // Handle callback.
    };

// Start the timer, make the web service call.
t.Start();
ws.GetRequest("Login","Username","Password");

Несколько замечаний:

  • Необходимо проверить как обратный вызов таймера, так и обратный вызов веб-службы, если другое условие не выполнено и если исключение не был брошен.Вы не хотите вызывать исключение дважды.
  • Вы не указали, как вы возвращаете исключение пользователю.Прямо сейчас это исключение будет выдано потоку, отличному от вызывающего потока.Это приведет к очень неприглядному исключению для пользователя.
  • Удаление экземпляра Timer обрабатывается в обратном вызове для веб-службы.Это предполагает, что обратный вызов для веб-службы будет всегда завершен, успешно или нет.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...