Padrões de evento fraca

Em aplicativos, é possível que os manipuladores que estão conectados a fontes de evento não serão destruídos em coordenação com o objeto de ouvinte anexado o manipulador para a fonte. Essa situação pode levar a vazamentos de memória. Windows Presentation Foundation (WPF)apresenta um padrão de design que pode ser usado para resolver esse problema, fornecendo uma classe de gerente dedicado para eventos específicos e a implementação de uma interface em ouvintes de evento. O padrão de design é conhecido como o padrão evento fraco.

Por que implementa o padrão de evento fraca?

Listening for events can lead to memory leaks. The typical technique for listening to an event is to use the language-specific syntax that attaches a handler to an event on a source. Por exemplo, em C#, essa sintaxe é: source.SomeEvent += new SomeEventHandler(MyEventHandler).

This technique creates a strong reference from the event source to the event listener. Normalmente, anexar um manipulador de eventos de um ouvinte faz com que o ouvinte para ter uma vida útil de objeto que é influenciada pelo tempo de vida do objeto de origem (a menos que o manipulador de eventos é removido explicitamente). Mas, em determinadas circunstâncias, convém o tempo de vida do objeto do ouvinte a ser controlada por outros fatores, como, por exemplo, se ele atualmente pertence à árvore visual do aplicativo e não pelo tempo de vida da origem. Sempre que o tempo de vida do objeto de origem estão ultrapassando o tempo de vida do objeto do ouvinte, o padrão de eventos normal leva a um vazamento de memória: o ouvinte é mantido em atividade mais do que o previsto.

O padrão do evento fraco foi projetado para resolver esse problema de vazamento de memória. O padrão de evento de baixa segurança pode ser usado sempre que uma escuta precisa registrar um evento, mas o ouvinte não sabe quando cancelar o registro explicitamente. O padrão do evento fraca também pode ser usado sempre que o tempo de vida do objeto de origem excede o tempo de vida útil de objeto do ouvinte. (Nesse caso, úteis é determinado por você.) O padrão do evento fraco permite que o ouvinte registrar e receber o evento sem afetar as características de tempo de vida do objeto do ouvinte de qualquer maneira. Na verdade, a referência implícita da fonte não determine se o ouvinte está qualificado para coleta de lixo. A referência é uma referência fraca, portanto a nomeação de padrão de evento fraca e relacionados APIs. The listener can be garbage collected or otherwise destroyed, and the source can continue without retaining noncollectible handler references to a now destroyed object.

Quem deve implementar o padrão de evento fraca?

Implementando o padrão do evento fraco é interessante principalmente para autores de controle. Como um autor de controle são amplamente responsável pelo comportamento e confinamento de seu controle e o impacto nos aplicativos em que está inserido. Isso inclui o comportamento de tempo de vida do objeto de controle, em particular o tratamento do problema de vazamento de memória descrito.

Certos cenários inerentemente prestam-se a aplicação do padrão evento fraco. Uma situação como essa é a ligação de dados. Vinculação de dados, é comum para o objeto de origem seja completamente independente do objeto listener, que é um alvo de uma ligação. Muitos aspectos do WPF vinculação de dados já têm o padrão do evento fraco aplicado em como os eventos são implementados.

Como implementar o padrão do evento fraco

Implementando o padrão do evento fraco consiste em três aspectos:

  • Derive a manager from the WeakEventManager class.

  • Implement the IWeakEventListener interface on any class that wants to register listeners for the weak event without generating a strong reference to the source.

  • When registering listeners, do not use the conventional add and remove accessors of the event where you want the listener to use the pattern. Em vez disso, use o AddListener e RemoveListener implementações em dedicado WeakEventManager para o evento.

WeakEventManager

Para implementar o padrão do evento de baixa segurança, você normalmente cria uma classe de gerente com uma relação 1: 1 para o evento. Por exemplo, se você tiver um evento chamado Spin, você criaria um SpinEventManager classe que é o Gerenciador de eventos de baixa segurança dedicada para o evento. Se o evento existe em mais de uma classe, comporta-se geralmente a mesma em cada classe e compartilha o mesmo tipo de dados de evento, o mesmo gerenciador pode ser usado para cada evento.

Quando você derivar a partir de WeakEventManager classe, substituir os dois métodos virtuais e expor vários outros membros cujos nomes não são especificamente regidos por um modelo virtual, mas devem existir no entanto. The overrides are used to initiate or terminate event delivery mode by the WPF infrastructure. Os outros membros fornecem funcionalidade para que seu próprio IWeakEventListener implementações podem usar o WeakEventManager para anexar ouvintes para o evento.

Para obter mais informações sobre a derivação de WeakEventManager, consulte o "Observações para herdeiros" seção de WeakEventManager tópico de referência.

IWeakEventListener

O IWeakEventListener interface tem um método de interface única chamado ReceiveWeakEvent. The ReceiveWeakEvent implementation must be a centralized implementation that directs any event reference that exists on that class to the appropriate WeakEventManager.

Para obter mais informações sobre como implementar a IWeakEventListener interface, consulte o "Observações para Implementers" seção de ReceiveWeakEvent tópico de referência do método.

Attaching Listeners

Suponha que você tenha um ClockwiseSpin evento (definido por um Spinner tipo) ou seja um convencional evento. Se você tiver um SpinListener classe listener que queira um ouvinte, a técnica convencional (sem usar o padrão do evento fraca) para anexar o manipulador seria usar o operador + =:

spinnerInstance.ClockwiseSpin += new EventHandler(MyOnCWSpinHandler);

Se você tiver uma classe que implementa IWeakEventListener e contas para o ClockwiseSpin evento e o seu gerente na implementação, a sintaxe para usar o padrão do evento fraco é:

ClockwiseSpinEventManager.AddListener(spinnerInstance, this);

Sua lógica de tratamento desse evento é especificada em um dos casos do ReceiveWeakEvent a implementação em sua classe, não como convencional baseado no delegado manipulador.

Implementing the Pattern for External Events

Um aspecto interessante do padrão de evento fraco é que você pode implementar o padrão em relação a um evento que não faz parte da base de código. From the perspective of the source, the way that handlers are attached to its event does not differ, and is controlled by the WeakEventManager. Você precisará definir um WeakEventManager para esse evento e a conta, em seguida, para que o evento como parte do ReceiveWeakEvent lógica de qualquer ouvinte potencial que deseja usar o padrão do evento fraco para ouvir eventos.

Consulte também

Referência

WeakEventManager

IWeakEventListener

Conceitos

Visão geral sobre eventos roteados

Revisão de Associação de Dados