Welcome to MSDN Blogs Sign in | Join | Help

This message cannot support the operation because it has been copied

Has this error message happened to you? It's because the lifetime of a message only lasts for one use. Once you've looked at the contents of a message, or copied the contents somewhere, you can't read the message again. This is a common problem encountered when people are trying to write a message inspector. Since you're expected to pass the message along after you're done inspecting it, it's quite likely that you'll need to make a new copy of the message. If you don't make a copy of the message, then the next person will have nothing to read.

This means that your message inspector code should look something like this:

public void AfterReceiveReply(ref Message reply, object correlationState)
{
MessageBuffer buffer = reply.CreateBufferedCopy(MaxMessageSize);

// Do something with the copied message reply = buffer.CreateMessage(); buffer.Close(); }
Published Wednesday, July 26, 2006 5:00 AM by Nicholas Allen
Filed under: , ,

Comments

Wednesday, July 26, 2006 8:29 AM by hah

# re: This message cannot support the operation because it has been copied

How about "Please try again in 0 seconds" Classic.
Wednesday, July 26, 2006 10:09 AM by Avner Kashtan

# re: This message cannot support the operation because it has been copied

Just to be clear - this is only relevant when *reading* a message, right?

I have a MessageInspector that adds a header before sending, and I haven't noticed any problems. Reading that header later did "burn" the message, as you've noted.

If this is such a common pattern, why is it not built into the framework? If 90% of all AfterReceiveReply implementations will have to include this boilerplate code, shouldn't the case be optimized for them, and allow NOT passing the message on through some explicit markup or command?
Wednesday, July 26, 2006 12:37 PM by Nicholas Allen

# re: This message cannot support the operation because it has been copied

We don't automatically copy the message because that's an expensive operation and we don't like doing expensive things behind your back.  Copying the message for you might require taking up gobs of memory or silently buffering streams.  Instead of explaining why you get this error message, we'd have to explain why your performance is so bad.  That's much harder to diagnose just from hearing the symptoms.
Wednesday, July 26, 2006 12:59 PM by Avner Kashtan

# re: This message cannot support the operation because it has been copied

Fair enough about the explicitness, but the current implementation - having the Message passed explicitly as 'ref' - just screams "you can modify the Message object and it will stick". Any way to make it more obvious from the code itself - not just the documentation - that this is what's happening?
Wednesday, July 26, 2006 2:22 PM by Nicholas Allen

# re: This message cannot support the operation because it has been copied

It would have been nice to be clearer here.  The name MessageInspector is confusing because this extensibility point does a whole lot more than let you "inspect" messages, which is why we can't do much to automate the process.  The problem is general to all users of the Message class though.  Custom channel authors have to deal with the same issue.  We might be able to create a new message implementation in the future to solve this.
Thursday, July 27, 2006 3:03 AM by Avner Kashtan

# re: This message cannot support the operation because it has been copied

How about changing the the name of the incoming Message parameter from "reply" to "singleUserReplyObject", or something less atrocious but which still conveys the fact that once touched this object is dead?
Thursday, July 27, 2006 3:25 AM by Avner Kashtan

# re: This message cannot support the operation because it has been copied

And another question (sorry for the harassment): I noticed that we're copying the message into a buffer, and then recreating the message from that buffer. My question is about your " // Do something with the copied message" comment - you mean with the original message, right?
Thursday, July 27, 2006 3:10 PM by Nicholas Allen

# re: This message cannot support the operation because it has been copied

"Do something with the copied message" means do something with the copy in the message buffer.  We can't do anything further with the original message, it's already been copied.  Unlike a message, you can use a message buffer more than once.
Sunday, July 30, 2006 1:52 AM by Avner Kashtan

# re: This message cannot support the operation because it has been copied

But the buffer is just that - an untyped byte buffer. To do something with it, I have to creat a temporary Message from the buffer, right?

I'm trying to think of a good balance here between explicitness (having the user aware of the buffer copy and the Message creation step) and being convenient/non-verbose (not requiring two distinct steps for a common operation like creating a copy of a message)
Monday, August 07, 2006 12:10 PM by Nicholas Allen's Indigo Blog

# Introducing MessageState

I've mentioned that messages have a definite lifecycle without ever mentioning what the lifecycle represents....
Monday, February 19, 2007 1:46 PM by Nicholas Allen's Indigo Blog

# Table of Contents Scratch Work

I haven't forgotten about the goal to put together a table of contents for all of these articles. The

Thursday, January 10, 2008 3:42 PM by Nicholas Allen's Indigo Blog

# Basing Authorization on the Message Body

How do I use a field in the message to answer an authorization request in ServiceAuthorizationManager?

New Comments to this post are disabled
 
Page view tracker