locked
Creating an async task with a timeout

    Question

  • I came up with this (untested) way of creating a async operation with timeout:

       cancellation_token_source cancelTokenSource;
        task<int> writeTask = create_task(outStream->WriteAsync(buffer))
        .then([size](DWORD written) {
          return outStream->FlushAsync();
        }).then([](bool) {
          return 1;
        }, cancelTokenSource.get_token());
        task<int> timeoutTask = create_task([timeout, cancelTokenSource](){
          std::this_thread::sleep_for(std::chrono::milliseconds(timeout));
          try {
            cancelTokenSource.cancel();
          } catch (Exception^ e) {
            e->Message;
          }
          return -1;
        });
        auto tasks = writeTask || timeoutTask;
        try {
          return tasks.get();
        }
        catch (Exception^ e) {
          e->Message;
        }

    The timeout thread just idles and then cancels the real task (that reads from a socket).

    Is this guaranteed to work always? Or can there be a race condition when the timeoutTask wants to trigger the cancelTokenSource.cancel() method and the real task just finished?

    Are there any other (more generic) ways (like a create_task_with_timeout) out there?

    Friday, July 11, 2014 1:00 AM

Answers

  • Hi,

    You can use:

     
    WaitForSingleObjectEx(smi_event_wait,1000,false);
    

    it can sleep 1 second and add a cancellation taken in the constructor then cancel the task:

     task<void>(create_async([]() {		
    		auto s = ref new StreamSocket();
    
    		/*
    		 * Connect to host
    		 */
    		task<void>(s->ConnectAsync(ref new HostName(ref new Platform::String(L"google.com")), ref new Platform::String(L"80"))).get();
    
    		auto reader = ref new DataReader(s->InputStream);
    
    		cancellation_token_source read_operation;
    
    		WRL::Wrappers::Event evt(CreateEventExW(NULL, NULL, CREATE_EVENT_MANUAL_RESET, EVENT_ALL_ACCESS));
    
    		/*
    		 * Start reading
    		 */
    		task<unsigned int>(reader->LoadAsync(100), read_operation.get_token()).then([&evt](task<unsigned int> t){
    			try
    			{
    				unsigned int num_read = t.get();				
    			}			
    			catch (...)
    			{
    			}
    			SetEvent(evt.Get());
    		});
    		
    		WaitForSingleObjectEx(evt.Get(), 1000, FALSE);
    
    		/*
    		 * Cancel the operation after 2 seconds of wait
    		 */
    		read_operation.cancel();
    
    		 FALSE);
    	})).then([](task<void> t) {});

    You can refer to the link below:

    http://msdn.microsoft.com/en-us/library/windows/apps/dd984117.aspx#tasks

    Best Wishes!


    We are trying to better understand customer views on social support experience, so your participation in this interview project would be greatly appreciated if you have time. Thanks for helping make community forums a great place. <br/> Click <a href="http://support.microsoft.com/common/survey.aspx?showpage=1&scid=sw%3Ben%3B3559&theme=tech"> HERE</a> to participate the survey.

    Monday, July 14, 2014 8:55 AM