0

Disclaimer: Not a professional developer

We're using SSIS to pull messages RabbitMQ, and I've managed to build a C# script component that pulls and pops messages off our queue for us using Queue.Dequeue(). So far, so good. However, we want to have some form of automatic check in place so our SSIS component won't be running continuously, but rather can be scheduled to run every n minutes.

I found the Dequeue(int timeout, out object result) method for this, and have managed to implement it like so: (we'd like the BasiocDeliverEventArgs result in order to process the body of the message)

object message;
myConsumer.Queue.Dequeue(millisecondsTimeout: 500, result:out message);
BasicDeliverEventArgs ea = (BasicDeliverEventArgs)message;

This seems to work, but somehow feel somewhat redundant to me. This, for example, seems more intuitive to me:

myConsumer.Queue.Dequeue(millisecondsTimeout: 500
     , result:out (BasicDeliverEventArgs)message)

But that yields an error specifying invalid arguments. Could someone please explain why it would throw that error, and why that syntax is invalid?

7
  • 1
    Because the C# language specification says so. Commented Jun 6, 2017 at 11:10
  • 1
    Wouldn't a typed queue be more helpful? Commented Jun 6, 2017 at 11:10
  • @PatrickHofman What is a typed queue? Just googled for it, but I didn't immediately see anyhting that'd explain more. As for the earlier comment, fair enough. I was hoping to find an explanation why it would say so . Commented Jun 6, 2017 at 11:15
  • 1
    Queue<T>. Look into generics. Commented Jun 6, 2017 at 11:16
  • 1
    @SchmitzIT since you are interested in learning, see this Fiddle I put together which will explain why. Commented Jun 6, 2017 at 12:26

2 Answers 2

2

You can't do this:

myConsumer.Queue.Dequeue(millisecondsTimeout: 500
 , result:out (BasicDeliverEventArgs)message)

because the Dequeue method is allowed to assign any object to the message parameter - it could be a "string", etc - which would lead to VeryBadThings™.

So no: you can't do that.

Sign up to request clarification or add additional context in comments.

3 Comments

Does VeryBadThings™ stand for something?^^
Still, the compiler could theoretically give Dequeue() its object and convert it to the callers parameter after/during the method. That would be a big mess with scopes etc.
@HenkHolterman it would also be a lot of mess for the under-the-covers implementation of ref etc - has consequences in more nuanced scenarios
1

The Dequeue method accepts object type in the 2nd parameter. But you are passing it a BasicDeliverEventArgs type. That is why you are getting the error. What if there are Employee, or SomeotherType in the queue, the method will not be able to assign it to the BasicDeliverEventArgs reference.

The owness is on the caller to convert it after the method has returned.

Also read this quote from MSDN:

The out keyword causes arguments to be passed by reference. It is like the ref keyword, except that ref requires that the variable be initialized before it is passed. To use an out parameter, both the method definition and the calling method must explicitly use the out keyword

In c# nearly everything inherits object so the method you have called can store any type in an object reference (so long as they inherit object) and return it to you. However it CANNOT store any type in BasicDeliverEventArgs reference and that's why it is not allowing it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.