BufferedReceiveMessageProperty.cs 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Runtime;
  7. using System.ServiceModel.Dispatcher;
  8. sealed class BufferedReceiveMessageProperty
  9. {
  10. const string PropertyName = "BufferedReceiveMessageProperty";
  11. MessageBuffer messageBuffer;
  12. static MessageBuffer dummyMessageBuffer = BufferedMessage.CreateMessage(MessageVersion.Default, string.Empty).CreateBufferedCopy(1);
  13. internal BufferedReceiveMessageProperty(ref MessageRpc rpc)
  14. {
  15. this.RequestContext = new BufferedRequestContext(rpc.RequestContext);
  16. rpc.RequestContext = this.RequestContext;
  17. this.Notification = rpc.InvokeNotification;
  18. }
  19. public static string Name
  20. {
  21. get { return PropertyName; }
  22. }
  23. // Implementation specifc storage
  24. public object UserState
  25. {
  26. get;
  27. set;
  28. }
  29. // The original RequestContext that was created by the ChannelHandler
  30. public BufferedRequestContext RequestContext
  31. {
  32. get;
  33. private set;
  34. }
  35. // The 'Manual Concurrency' notification which allows higher layers to notify the dispatcher of an event
  36. // e.g. The event associated with re-pumping the above buffered RequestContext again
  37. internal IInvokeReceivedNotification Notification
  38. {
  39. get;
  40. private set;
  41. }
  42. public void RegisterForReplay(OperationContext operationContext)
  43. {
  44. this.messageBuffer = (MessageBuffer)operationContext.IncomingMessageProperties[ChannelHandler.MessageBufferPropertyName];
  45. // cannot remove the MessageBufferProperty from messageProperties because it causes the message buffer associated with the property
  46. // to be disposed of. Assigning null to the property has the same effect, so we assign dummyMessageBuffer to the property.
  47. operationContext.IncomingMessageProperties[ChannelHandler.MessageBufferPropertyName] = dummyMessageBuffer;
  48. }
  49. public void ReplayRequest()
  50. {
  51. Message requestMessage = this.messageBuffer.CreateMessage();
  52. // re-injecting the MessageBufferProperty here so that it can be reused by the dispatch layer
  53. // (ChannelHandler.DispatchAndReleasePump to be specific) instead of recreating the buffer for replay.
  54. requestMessage.Properties[ChannelHandler.MessageBufferPropertyName] = this.messageBuffer;
  55. this.RequestContext.ReInitialize(requestMessage);
  56. }
  57. public static bool TryGet(Message message, out BufferedReceiveMessageProperty property)
  58. {
  59. Fx.Assert(message != null, "The Message parameter is null");
  60. return TryGet(message.Properties, out property);
  61. }
  62. public static bool TryGet(MessageProperties properties, out BufferedReceiveMessageProperty property)
  63. {
  64. Fx.Assert(properties != null, "The MessageProperties parameter is null");
  65. object value = null;
  66. if (properties.TryGetValue(PropertyName, out value))
  67. {
  68. property = value as BufferedReceiveMessageProperty;
  69. }
  70. else
  71. {
  72. property = null;
  73. }
  74. return property != null;
  75. }
  76. }
  77. }