AsyncCallBack — должен ли он быть статичным/должен ли он возвращать void?

Мой вопрос довольно прост, но я подозреваю, что ответа не будет. В моем приложении WP7 я вызываю веб-службу REST, чтобы ПОЛУЧИТЬ некоторые данные, которые я десериализую в объекты класса.

Мой метод запроса и его метод AsyncCallBack находятся внутри класса (MVVM ViewModel) и вызываются внутри метода экземпляра класса (LoadData).

AsyncCallBack десериализует json, полученный из веб-службы, в объект. Мне нужно добавить этот объект в коллекцию класса, где все это происходит, например:

this.Collection1.Add(retrievedObject); 

Конечно, поскольку AsyncCallBack является статическим, я не могу получить доступ к ключевому слову this. Я также не могу вернуть полученный объект вызывающей стороне, потому что AsyncCallBack должен возвращать значение void. Я понимаю, что, вероятно, стал жертвой какого-то элементарного непонимания. Как мне это решить?

Спасибо!


person Andrew B Schultz    schedule 01.09.2012    source источник
comment
Почему ваш AsyncCallback должен быть статичным?   -  person Lee    schedule 01.09.2012
comment
Это не так; но я заметил, что это всегда в примерах. Я беспокоюсь, что если сделать его нестатическим, он не будет потокобезопасным или что-то в этом роде. Как я уже сказал, я не очень хорошо знаком с этими методами ... но если это не проблема, то, пожалуйста, дайте мне знать, так как это ответит на мой вопрос! Просто сделав AsyncCallBack методом экземпляра и выполнив this.Collection1.Add(retrievedObject) внутри AsyncCallBack, я получаю исключение Invalid cross-thread access.   -  person Andrew B Schultz    schedule 01.09.2012
comment
Ваш обратный вызов, вероятно, будет вызываться в потоке, отличном от пользовательского интерфейса, поэтому вам может потребоваться синхронизировать доступ к вашей коллекции (или использовать потокобезопасную коллекцию), но нет необходимости, чтобы ваш обратный вызов был статическим методом.   -  person Lee    schedule 01.09.2012
comment
Вы не можете получить доступ к каким-либо элементам управления из любого другого потока, кроме основного потока (т.е. потока, создавшего элементы управления). Вам нужно использовать Dispatcher для запуска этого кода в основном потоке. См.: stackoverflow.com/questions/6238064/   -  person Guffa    schedule 01.09.2012
comment
Спасибо вам, ребята! Как только вы указали на основные проблемы, я нашел это отличное решение в ответе @SteveWillcock: stackoverflow.com/questions/3420282/   -  person Andrew B Schultz    schedule 01.09.2012


Ответы (2)


Должен ли он быть статичным? Нет.

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

Должен ли он возвращаться недействительным? да.

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

person Guffa    schedule 01.09.2012
comment
Потрясающе - спасибо! Вот (как мне кажется) отличный метод обработки потоков: ответ Стива Уилкока в этой теме: stackoverflow.com/questions/3420282/ - person Andrew B Schultz; 01.09.2012

Прочитайте, как использовать шаблон асинхронного программирования (APM): msdn.microsoft.com/en-us/library/ms228963.aspx.

person Paul Michalik    schedule 01.09.2012