/// <summary> /// ReleaseOnChannel /// </summary> void DUCE.IResource.ReleaseOnChannel(DUCE.Channel channel) { // reconsider the need for this lock using (CompositionEngineLock.Acquire()) { Debug.Assert(_duceResource.IsOnChannel(channel)); //release from this channel _duceResource.ReleaseOnChannel(channel); if (!_duceResource.IsOnAnyChannel) { // If this was the last reference on the channel then clear up our state. // Again, we assume here that if the target DependencyObject is animated that // it will be associated with a Dispatcher and that this animation resource // will also be associated with that Dispatcher's channel. DependencyObject d = (DependencyObject)_dependencyObject.Target; // DependencyObject shouldn't have been garbage collected before we've // released all of its property animation resources. Debug.Assert(d != null); // The target DependencyObject should be associated with a Dispatcher. Debug.Assert(d.Dispatcher != null); // Make sure the target belongs to this thread Debug.Assert(d.CheckAccess()); // If we're invalid, that means we've added our _updateResourceHandler to the // MediaContext's ResourcesUpdated event. Since we've been entirely released // from the channel we can cancel this update by removing the handler. if (!_isValid) { MediaContext mediaContext = MediaContext.From(d.Dispatcher); mediaContext.ResourcesUpdated -= _updateResourceHandler; _isValid = true; } _updateResourceHandler = null; } } }
/// <summary> /// Do the actual work to disconnect the VisualTarget. /// This is called (on the channel's thread) either from /// DisconnectHostedVisual or from DoPendingDisconnect, /// depending on which thread the request arrived on. /// </summary> private void Disconnect(DUCE.Channel channel, Dispatcher channelDispatcher, DUCE.ResourceHandle hostHandle, DUCE.ResourceHandle targetHandle, DUCE.MultiChannelResource contentRoot) { channelDispatcher.VerifyAccess(); DUCE.CompositionNode.RemoveChild( hostHandle, targetHandle, channel ); // // Release the targets handle. If we had duplicated the handle, // then this removes the duplicated handle, otherwise just decrease // the ref count for VisualTarget. // contentRoot.ReleaseOnChannel(channel); SetFlags(channel, false, VisualProxyFlags.IsContentNodeConnected); }