C # Как мне передать больше, чем просто IAsyncResult в AsyncCallback?

#c# #asynchronous #httpwebrequest #iasyncresult #asynccallback

#c# #асинхронный #httpwebrequest #iasyncresult #asynccallback

Вопрос:

Как мне передать больше, чем просто IAsyncResult в AsyncCallback?

Пример кода:

 //Usage
var req = (HttpWebRequest)iAreq;
req.BeginGetResponse(new AsyncCallback(iEndGetResponse), req);

//Method
private void iEndGetResponse(IAsyncResult iA, bool iWantInToo) { /*...*/ }
  

Я хотел бы передать переменную example bool iWantInToo . Я не знаю, как добавить это в new AsyncCallback(iEndGetResponse) .

Ответ №1:

Вы должны использовать состояние объекта, чтобы передать его. Прямо сейчас вы передаете req параметр — но вместо этого вы можете передать объект, содержащий как его, так и логическое значение.

Например (используя кортеж .NET 4 — если вы используете .NET <=3.5, вы можете использовать пользовательский класс или KeyValuePair, или аналогичный):

 var req = (HttpWebRequest)iAreq;
bool iWantInToo = true;
req.BeginGetResponse(new AsyncCallback(iEndGetResponse), Tuple.Create(req, iWantInToo));

//Method
private void iEndGetResponse(IAsyncResult iA) 
{
    Tuple<HttpWebRequest, bool> state = (Tuple<HttpWebRequest, bool>)iA.AsyncState;
    bool iWantInToo = state.Item2;

    // use values..
}
  

Комментарии:

1. Очень, очень интересно. Тестирую это сейчас. Я никогда раньше не видел этого соглашения с кортежем, выглядит очень полезным!

2. Никто не видит этот метод уродливым? Предполагается, что передавать параметры лучше.

3. @derek этот шаблон, в общем, был заменен для асинхронной работы. большинство новых API работают с Task <T>

4. @ReedCopsey Итак, современный способ — использовать «await», чтобы завершить обратный вызов, а затем выполнить работу, которую ранее выполнял «обратный вызов»?

5. @дерек Да. await делает обратные вызовы ненужными