How to end up a thread while encounter a task exception in a ".then" contuation task

Aug 14, 2014 at 9:51 AM
Well, the following codes are capsulated in a thread. Is there any way to quit the thread when catch an exception in the "catch" sub block?
      .then([&](http_response resp)        
      {
            try
    {
        resp_json = resp.get();
    }
    catch (const std::exception& e)
    {
        excep_str = L"Caught exception: ";
        excep_str.AppendFormat(_T("%s"), e.what());
        MessageBox(excep_str);
        return;                          //this will just return to the thread function and go on
    }       
       }
       // the left codes in thread function
       ......      
Coordinator
Aug 18, 2014 at 5:30 PM
Hi joeccmou,

I'm a little confused as to what you are asking. The task continuation (specified in the .then function) is running on a thread pool. What do you mean by 'quit the thread'? When you return from the task continuation the thread pool thread will be free to run something else. Are you talking about canceling any additional task continuations that might be hooked up?

I recommend you take a look at this document for more information about how PPL tasks and continuations work.

Steve
Aug 20, 2014 at 3:35 AM
Hi Steve

I have read the document mentioned above before and I'm sorry for my unclear questioning. Well, I mean that when I catch a exception in a .then task, how can I quit the function which runs the .then task or simply close the window or Win32 application. For example

void CFingerPrint::OnButtonClickRun()
{
 client.request(...).then([&](http_response resp)        
  {
        try
        {
             resp_json = resp.get();
          }
        catch (const std::exception& e)
         {
               excep_str = L"Caught exception: ";
               excep_str.AppendFormat(_T("%s"), e.what());
               MessageBox(excep_str);
                return;                          //this will return to the OnButtonClickRun function and go on
         }       
   }
   // the left codes in OnButtonClickRun function
   ......      
}

Is there any way to quit the OnButtonClickRun function except setting a BOOL flag when catch an exception?

Joecc
Coordinator
Aug 21, 2014 at 12:48 AM
Hi Joecc,

I think you are confused a bit. The http_client::request method is asynchronous, so it will immediately return and you will continue to run your OnButtonClickRun function. The task continuation you have hooked up with the .then function will get executed at a later time on a different thread. If you want to take some action in your task continuation when an exception occurs you will have to so some signaling or something like set and event. How do you normally exit your application when an errors occurs?

If you want to set a bool variable when an exception occurs you can capture a reference to one in the lambda provided to your task continuation.

Steve
Aug 21, 2014 at 4:08 AM
Hi Steve,

Thanks for your reply. If the OnButtonClickRun function is running on thread A( for example) and .then task is running on thread B, does it mean every .then task runs a new thread such as thread C, D, E ,F.... ?

I will call PostQuitMessage(0) to exit the application when an error occurs . But now I just want to end up or go on the execution of OnButtonClickRun function according to whether an exception occurs or not. I try a BOOL reference and it confuses me. Normally, exceptions never occurs, so the statement (1) will always be true and the statement(2) will never run.

void CFingerPrint::OnButtonClickRun()
{
  bool       ex_flag = false;        
  http_response  http_resp;

  client.request(...).then([&](http_response resp)        
  {
       try
       {
           http_resp = rsp;
       }
      catch (const std::exception& e)
      {
              ex_flag = true;
            excep_str = L"Caught exception: ";
            excep_str.AppendFormat(_T("%s"), e.what());
            MessageBox(excep_str);
             return;                                        
      }       
   } .wait()             // wait the task complete

   if(ex_flag)          //   (1) 
      return;

  json::value json_obj = http_resp.extract_json() ;    // (2) 
  ......      
}

Now I use the following code instead

void CFingerPrint::OnButtonClickRun()
{
  http_response  http_resp;
    try 
    {
        http_resp = client.request(request).get();
    }
   catch (const std::exception& e)
   {
       ex_flag = true;
       excep_str = L"Caught exception: ";
       excep_str.AppendFormat(_T("%s"), e.what());
       MessageBox(excep_str);
       return;                                        
    }       

    json::value json_obj = http_resp.extract_json() ;
}

joecc
Coordinator
Aug 21, 2014 at 5:31 PM
Hi Joecc,

Every task could be running on a different thread, but really they are running on a thread pool so there isn't the cost and expense of creating a new thread each time.

If you don't care about the OnButtonClickRun being asynchronous then I would recommend code like the following. I'm not sure how your above code was compiling because extract_json is asynchronous and returns a task<json::value>. The reason you might be confused with your first code snippet is because you are not using a task based continuation, the http_response assignment is never going to throw an exception.
json::value json_obj;
try
{
    http_response response = client.request(request).get();
    json_objc = response.extract_json().get();
} catch(const std::exception &e)
{
    // Handle and return
    return;
}
// If you have reached here the json_obj variable contains the result....
Steve
Sep 1, 2014 at 5:25 AM
HI Steve,
          This is what I need. Thank you.