Azure Worker Role Asynchronous Receive message: ho

2019-08-29 00:11发布

问题:

Sample code here

public override void Run()
{
   while (true)
   {
    IAsyncResult result = CUDClient.BeginReceive(TimeSpan.FromSeconds(10),  OnMessageReceive, CUDClient);
    Thread.Sleep(10000);
   }
}

I have tested this Azure worker role. I kept 100 messages in the Service bus Queue. It's doing entities updates as a operation(Entity framework). It took 15 minutes to process all the queues and looks like taking longer time. Any suggestion to improve this?

Thanks in Advance

回答1:

Try this one...

  //Somefunction
    IAsyncResult result = CUDClient.BeginReceive(OnMessageReceive, CUDClient); 

    while (true)
        Thread.Sleep(1000); //In case you are using thread

    //Somefunction End

public static void OnMessageReceive(IAsyncResult result)
    {
        CUDClient.BeginReceive(OnMessageReceive, CUDClient);
        SubscriptionClient queueClient = (SubscriptionClient)result.AsyncState;
        IBusinessLogicProvider Obj;
        try
        {
            //Receive the message with the EndReceive call
            BrokeredMessage receivedmsg = queueClient.EndReceive(result);
                //receivedmsg = CUDClient.Receive();
                if (receivedmsg != null)
                {
                    switch (receivedmsg.ContentType)
                    {
                        case "Project":
                            Obj = new ProjectsBL();
                            Obj.HandleMessage(receivedmsg);
                            receivedmsg.BeginComplete(OnMessageComplete, receivedmsg);
                            break;
                     }
                 }
          }
    }


回答2:

Actually Service Bus is very fast enough in my experience. What wrong with you is "Thread.Sleep(10000)";

Sleeping 10 sec for each message. For 100 messages 100*10 = 10000 seconds = 16.67 minutes So this is a problem for the delay...

Solution:

Dont use Thread.Sleep(10000); (Its not suitable for BeginReceive, only suitable for Receive)

public override void Run() //This should not be a Thread...If its a thread then your thread will terminate after receiving your first message
{
    IAsyncResult result = CUDClient.BeginReceive(**TimeSpan.MaxValue**,  OnMessageReceive, CUDClient);
}

//Function OnMessageReceive
{
 //Process the Message
 **IAsyncResult result = CUDClient.BeginReceive(TimeSpan.MaxValue,  OnMessageReceive, CUDClient);**
}

using TimeSpan.MaxValue your connection to the SB will be preserved for longtime. so no frequent null message(less cost)...



回答3:

Try using XecMe Parallel task for processing the message reading.

XecMe @ xecme.codeplex.com



回答4:

I tried this.

while (true)
        {
           //read all topic messages in sequential way....           
           IAsyncResult result = CUDClient.BeginReceive(OnMessageReceive, CUDClient); 
           Thread.Sleep(1000);
        }  
public static void OnMessageReceive(IAsyncResult result)
    {
        SubscriptionClient queueClient = (SubscriptionClient)result.AsyncState;
        IBusinessLogicProvider Obj;
        try
        {
            //Receive the message with the EndReceive call
            BrokeredMessage receivedmsg = queueClient.EndReceive(result);
                //receivedmsg = CUDClient.Receive();
                if (receivedmsg != null)
                {
                    switch (receivedmsg.ContentType)
                    {
                        case "Project":
                            Obj = new ProjectsBL();
                            Obj.HandleMessage(receivedmsg);
                            receivedmsg.BeginComplete(OnMessageComplete, receivedmsg);
                            break;
                     }
                 }
          }
    }

It processed all the 100 messages in 1 minute(00:01:02) . A lot better than previous one.