1

I want to give the consumer of my event the possibility to modify a buffer through EventArgs, but I can't pin the solution properly. I'm well prepared in C/C++ but rather inexperienced in C#.

My Event definition is:

public class ResponseEventArgs : EventArgs
{
    public byte[] Buffer { get; set;  }

    public ResponseEventArgs(byte[] buffer)
    {
        this.Buffer = buffer;
    }
}

public delegate void ResponseEventHandler(object sender, ResponseEventArgs e);
public event ResponseEventHandler Response;

I raise the event with:

 byte[] buffer = new byte[BUFSIZE];

 Response(this, new ResponseEventArgs(buffer));

A sample event handler, where I convert to UTF8, replace, and back to byte, e.g:

void Response_Test(object sender, ResponseEventArgs e)
{      
    string stringBuf = System.Text.Encoding.UTF8.GetString(e.Buffer);

    stringBuf = stringBuf.Replace("A", "B");

    e.Buffer = new byte[stringBuf.Length * sizeof(char)];
    System.Buffer.BlockCopy(stringBuf.ToCharArray(), 0, e.Buffer, 0, 
                            e.Buffer.Length);        
}

When returning from the event, the byte buffer is still with the old content.

AstroCB
  • 12,337
  • 20
  • 57
  • 73
Hernán
  • 4,527
  • 2
  • 32
  • 47

1 Answers1

3

After the event, you need to check ResponseEventArgs.Buffer, rather than your local buffer. Reason being, your event handler is creating a new buffer inside your ResponseEventArgs and modifying that one, not the original one you created before the event call. To get the new buffer, you have to grab the reference directly from the ResponseEventArgs.

Here's one correct way to do it:

byte[] buffer = new byte[BUFSIZE];

//create the event args separately so we can reference it after the raise event call.
var args = new ResponseEventArgs(buffer);

Response(this, args);  //Raise the event

//get the current/new buffer from the event args
var modifiedBuffer = args.Buffer;
Nathan A
  • 11,059
  • 4
  • 47
  • 63
  • That's it, i'm a little distracted today. Thank you very much. – Hernán Jul 08 '14 at 22:34
  • 1
    Why do we allocate the buffer at the beginning if it is going to be replaced anyway? – AlexD Jul 08 '14 at 22:52
  • @AlexD no idea... I'm assuming the Op removed the code that actually populated the original buffer for simplicity's sake. – Nathan A Jul 08 '14 at 22:54
  • @AlexD You don't *have to*, it all depends on the contract of `ResponseEvent` and if subscribers are expected to have an array or not pre-provied. – Scott Chamberlain Jul 08 '14 at 22:55
  • @ScottChamberlain Sure, in principle yes. But I believe that in the context of the question the buffer is pre-allocated specially to be filled. And (again, in the scope of the question), first allocation could look rather confusing. – AlexD Jul 08 '14 at 23:00
  • 1
    @NathanA I can be wrong of course, but my understanding is that the original idea of OP was to allocate the buffer and then let the handler to fill it (pretty usual way in C++). You propose a more elegant approach which invalidates the need of pre-allocation completely. – AlexD Jul 08 '14 at 23:19