locked
Async operations in loop

    Question

  • I am doing multicast from my c++ metro app from two ip addresses using datagram socket. The ip addresses are stored in a vector .The below is the code of sending the multicast request. The StartMulticast() function starts the multicast.

    	std::vector<String^>IpArray;
    	IpArray.push_back( ip1);
    	IpArray.push_back( ip2 );
    
    	std::for_each( begin( IpArray), end( IpArray),[this]( String^ ips )
    	{		
    		create_task([this,ips]()
    		{
    			
    				IAsyncAction^ Action = StartMulticast( ips );
    				task<void> Task = create_task( Action );
    				Task.then([this]()
    				{
    				}).wait();
    		});
    	});

    Below is the actual StartMulticast function.

    Windows::Foundation::IAsyncAction^ MainPage::StartAsync1( String^ ip )
    {
    	return create_async([this,ip]()
    	{
    
    					DatagramSocket^ Socket = ref new DatagramSocket();
    					Socket->Control->QualityOfService = SocketQualityOfService::Normal;
    					Socket->MessageReceived += ref new TypedEventHandler<DatagramSocket^, DatagramSocketMessageReceivedEventArgs^>(this, &MainPage::MessageReceived);
    					HostName^ hst = ref new HostName( ip );
    					task<void>(Socket->BindEndpointAsync( hst,"" )).then([this,Socket] (task<void> previousTask)
    					{		
    						try
    						{		
    							previousTask.get();
    							HostName^ MultiCastHost = ref new HostName( "mulicast ip" );
    							Socket->JoinMulticastGroup( MultiCastHost );
    							task<IOutputStream^>(Socket->GetOutputStreamAsync( MultiCastHost, "port")).then([this,Socket] ( task<IOutputStream^> stream )
    							{
    								try  
    								{
    									IOutputStream^ MyStrem = stream.get();					
    									String^ MesageIDString = ""; 
    									// Fille  message to be sent on network.
    									DataWriter^ Writer = ref new DataWriter( MyStrem );
    									Writer->WriteString( MesageIDString );
    									try
    									{
    										task<unsigned int>(Writer->StoreAsync()).then([this,Socket]( task<unsigned int> WriteTask )						
    										{
    											try
    											{
    												WriteTask.get();
    												task<bool>(Socket->OutputStream->FlushAsync()).
    												then([this](task<bool> bVal)
    												{
    													try
    													{
    														bVal.get();
    													}
    													catch(Exception^ e)
    													{
    														String^ ErrorMsg = e->Message;
    													}
    												}).wait();
    
    											}
    											catch( Exception^ Exp )
    											{
    												String^ ErrorMsg = Exp->Message;
    											}
    										}).wait();
    									}
    									catch( Exception^ Exp )
    									{
    									String^ ErrorMsg = Exp->Message;
    									}
    								}
    								catch(  Exception^ Exp )
    								{
    								String^ ErrorMsg = Exp->Message;
    								}			
    								}).wait();
    						}
    						catch( ... )
    						{
    						}
    					}).wait();
    
    	});
    }

    The problem is when I run the app the , MessageReceived() callback is not getting called so that I am not getting any replies. But it works single ip instead of two ips in a loop. May be because the local socket object goes out of scope. It looks like a timing issue. What could be wrong? What is the best practice of invoking async operation in a loop in this type of situations, especilly when response to the request is recevived in another callback like MessageReceived() function here.

    • Edited by its_me_here Saturday, December 15, 2012 6:44 PM
    Saturday, December 15, 2012 6:42 PM

All replies

  • HI,

    How about use different callback functions for different sockets.

    In the loop two socket will use one callback function.
    Socket->MessageReceived +=

    I think it will be caused problem.

    Best regards,
    Jesse


    Jesse Jiang
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    • Proposed as answer by Jesse Jiang Wednesday, December 19, 2012 6:06 AM
    Monday, December 17, 2012 7:13 AM
  • Thanks Jesse, for your reply. Let me restart the discussion after a long period! In my case, I cannot have a separate callback function for each socket. That would need a lot of duplication. Also, the callback function does the same thing for all sockets. So there is no need to duplicate. Any inputs? If there are two sockets, when the second socket tries to bind to the second ip using BindEndPointAsyc, the first socket might already be bound to the first IP. That too might be reason why the callback is not getting called. Is there anyway by which I can ensure that the second socket binds to the second IP, after the first IP has bound and called FlushAsync() so that the second socket can connect?

    Friday, January 4, 2013 8:31 AM