IGeoPositionWatcher <GeoPosition>.PositionChanged не запускается, но GeoCoordinateWatcher.PositionChanged является - PullRequest
3 голосов
/ 13 октября 2010

Я пытаюсь написать приложение, которое отслеживает местоположение компьютера, используя пространство имен .net 4.0 System.Device.Location.Однако я обнаружил, что событие GeoCoordinateWatcher.PositionChanged вызывается только при регистрации в событии класса, а не при использовании интерфейса, который он реализует.

Вот рабочая версия кода:

using (GeoCoordinateWatcher geoCoordinateWatcher = new GeoCoordinateWatcher())
{
    geoCoordinateWatcher.PositionChanged += (sender, args) => Console.WriteLine(args.Position);
    geoCoordinateWatcher.Start();

    Thread.Sleep(2000);
}

Выводит объект позиции, как я и ожидал.Когда я изменяю код на это:

using (GeoCoordinateWatcher geoCoordinateWatcher = new GeoCoordinateWatcher())
{
    IGeoPositionWatcher<GeoCoordinate> positionWatcher = geoCoordinateWatcher;
    positionWatcher.PositionChanged += (sender, args) => Console.WriteLine(args.Position);
    positionWatcher.Start();

    Thread.Sleep(2000);
}

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

Что я делаю не так?Есть ли что-то тонкое, что я неправильно понимаю в событиях на общих интерфейсах?

Спасибо

Энди

РЕДАКТИРОВАТЬ:

Я думаю, что это может быть ошибка вКод Microsoft.Я взглянул на System.Device.dll в рефлекторе .net и обнаружил, что GeoCoordinateWatcher имеет 2 реализации события PositionChanged.Первая - прямая реализация своего собственного события PositionChanged, вторая - явная реализация события IGeoPositionWatcher.PositionChanged.

Второй, похоже, больше не используется в коде.

Мне также удалось найти быстрый обходной путь, унаследовав от GeoCoordinateWatcher и реализовав событие интерфейсов PositionChanged самостоятельно:

public class MyGeoCoordinateWatcher : GeoCoordinateWatcher, IGeoPositionWatcher<GeoCoordinate>
{
    event EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>> IGeoPositionWatcher<GeoCoordinate>.PositionChanged
    {
        add { base.PositionChanged += value; }
        remove { base.PositionChanged -= value; }
    }
}

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

Спасибо

РЕДАКТИРОВАТЬ:

Поднял это в Microsoft Connect: https://connect.microsoft.com/VisualStudio/feedback/details/613235/igeopositionwatcher-geocoordinate-positionchanged-event-does-not-fire-on-geocoordinatewatcher-class

Ответы [ 2 ]

1 голос
/ 13 октября 2010

Я полностью согласен с вашим диагнозом, приятного сна. Явная реализация интерфейса обновляет поле с именем m_positionChanged. Событие PositionChanged обновляет поле делегата с именем PositionChanged.

Вдохновленный, чтобы увидеть, как большие мальчики нащупывают это. Для этого нет простого обходного пути, кроме как взломать рефлексию и получить прямой доступ к приватным полям. Вы можете сообщить об ошибке на connect.microsoft.com. Просто ссылка на эту ветку должна дать им все, что им нужно.

0 голосов
/ 05 апреля 2011

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

...