none
[C++]task.wait() in a catch-block throws exception

    Question

  • Hi,

    I'm working on a windows store app using c++ and I'm stuck at this problem:

    I'm using an event handler to catch unhandled exceptions:

    CoreApplication::UnhandledErrorDetected += ref new EventHandler<UnhandledErrorDetectedEventArgs^>(this, &App::OnUnhandledException);
    	

    then I try to write the exception and (more importantly) the previously logged events to a file:

    void App::OnUnhandledException(Platform::Object ^sender, UnhandledErrorDetectedEventArgs ^e)
    {
    	if (!e->UnhandledError->Handled){
    		try{
    			e->UnhandledError->Propagate();
    		}
    		catch (Exception ^e){
    			log->Critical(e->Message);
    			create_task(logSession->Save()).wait();
    			throw(e);
    		}
    	}
    }

    where logSession->Save() uses the Windows::Diagnostics::LogSession::SaveToFileAsync and must therefore necesseraly be asynchronous:

    return session->SaveToFileAsync(folder, "Log " + time.wMonth + "-" + time.wDay + "-" + time.wYear + " - " + time.wHour + "-" + time.wMinute + "-" + time.wSecond + ".etl");

    The problem is, as OnUnhandledException is (sometimes?) executed on the UI thread, .wait() throws "An invalid parameter was passed to a function that considers invalid parameters fatal" (well at least I think that's the reason, if I delete the .wait() the exception disappears).

    Is there any way to avoid this? I have to wait for the asynchronous call to complete to make sure the log file is correctly created.



    • Edited by Liechtenschwein Tuesday, February 02, 2016 11:25 PM
    • Edited by Fred Bao Thursday, February 04, 2016 9:38 AM add the tag
    Tuesday, February 02, 2016 11:21 PM

All replies

  • Hi Liechtenschwein,

    >> as OnUnhandledException is (sometimes?) executed on the UI thread, .wait() throws "An invalid parameter was passed to a function that considers invalid parameters fatal"

    Not quite understand if the OnUnhandledException does executed on UI thread, will the exception always been thrown? Probably use dispatcher to make sure all the codes executed on the UI thead?

        auto dispatcher = Windows::UI::Core::CoreWindow::GetForCurrentThread()->Dispatcher;
        dispatcher->RunAsync(Windows::UI::Core::CoreDispatcherPriority::Normal,
            ref new Windows::UI::Core::DispatchedHandler(
            [=]()
        {
           .....
        }));

    Anyway I think better to follow up this blog: http://blogs.msdn.com/b/win8devsupport/archive/2012/10/26/how-to-debug-a-task-exception-in-windows-store-application.aspx to see how we can find the root cause of the issue instead of simply guess. Also I'm not quite sure when and where the exception will thrown simply from your description.

    --James


    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.
    Click HERE to participate the survey.

    Wednesday, February 03, 2016 5:54 AM
  • Hi James,

    I must admit that I'm not that much into multithreading debugging, so thanks for the link, really helpful!

    But besides this specific exception, I'ld like a way to catch all the unhandled exceptions that occur during the lifetime of my app to assure that in case of an unscheduled exception, the log is saved to a file. UnhandledErrorDetected seems to do the trick (at least for some exceptions), but it seems to be executed on the UI thread, which I think causes the problem

    Greetings Liechtenschwein

    Wednesday, February 03, 2016 12:33 PM
  • Hello Liechtenschwein,

    >>The problem is, as OnUnhandledException is (sometimes?) executed on the UI thread, .wait() throws…

    It is not sure whether if this issue is caused from UI thread from these current posted information. Could you please share us a repro project so that we could make a test with it?

    Regards.


    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.

    Thursday, February 04, 2016 10:01 AM
  • I'm sorry for the delay. Here you are: Test app

    It's basically just a hub app with an added unhandledexception-handler:

    App::App(){
    	//...
    
    	//Register handler for unhandled exceptions
    	Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected += ref new Windows::Foundation::EventHandler<Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^>(this, &App::OnUnhandledException);
    }
    
    void App::OnUnhandledException(Platform::Object ^sender, Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs ^e)
    {
    	if (!e->UnhandledError->Handled) {
    		try {
    			e->UnhandledError->Propagate();
    		}
    		catch (Exception ^e) {
    			
    			//Do some logging, which necessarily has to be async and has to be completed before the app shuts down
    			create_task([]() {
    
    				//do some stuff
    				int a = 1 + 2;
    
    			}).wait();		//This throws a Concurrency::invalid_operation, as it's executed on the UI-thread (?)
    
    			throw(e);
    		}
    	}
    }

    that throws at some point of the execution

    void HubPage::ItemView_ItemClick(Object^ sender, ItemClickEventArgs^ e)
    {
    	//...
    
    	//Somewhere in the app some error occurs
    	throw ref new COMException(-1, "Test exception");
    }



    Thursday, February 18, 2016 4:41 PM
  • >>It's basically just a hub app with an added unhandledexception-handler:

    If it is a normal hub app, please have a try to use the UnhandledException, which is exposed by the Application object in that app model:

    https://msdn.microsoft.com/en-us/library/windows.applicationmodel.core.icoreapplicationunhandlederror.unhandlederrordetected.aspx

    Friday, February 19, 2016 9:02 AM
  • I did some changes, but this doesn't change anything about the error occuring:

    this->UnhandledException += ref new Windows::UI::Xaml::UnhandledExceptionEventHandler(this, &App::OnUnhandledException);
    //Windows::ApplicationModel::Core::CoreApplication::UnhandledErrorDetected += ref new Windows::Foundation::EventHandler<Windows::ApplicationModel::Core::UnhandledErrorDetectedEventArgs^>(this, &App::OnUnhandled);

    void App::OnUnhandledException(Platform::Object ^sender, Windows::UI::Xaml::UnhandledExceptionEventArgs ^e)
    {
    	if (!e->Handled) {
    		//Do some logging, which necessarily has to be async and has to be completed before the app shuts down
    		create_task([]() {
    
    			//do some stuff
    			int a = 1 + 2;
    
    		}).wait();		//This throws a Concurrency::invalid_operation, as it's executed on the UI-thread (?)
    	}
    }

    Friday, February 19, 2016 10:49 AM
  • I actually had similar issues with IAsyncOperations running synchronously converted to tasks, but when running in thread pool thread.
    Friday, February 19, 2016 11:48 AM
  • For OnSuspend, there is a solution for this problem that looks quit straightforward:

    void App::OnSuspending(Object^ sender, SuspendingEventArgs^ e)
    {
    	SuspendingDeferral ^d = e->SuspendingOperation->GetDeferral();
    
    
    	create_task(/*DoSomeAsyncStuff*/).then([d](){
    		d->Complete();
    	});
    }

    What I need is something similar for OnUnhandledError/OnUnhandledException. Even the build-in logging (Windows::Foundation::Diagnostics::LoggingSession) requires an async-method to complete to save the logging to a file. Thus, if I want to log an unhandled error, I need this method to complete before the app shuts down, otherwise I'm left with a half-finished log-file :/


    Friday, February 19, 2016 4:28 PM
  • >>What I need is something similar for OnUnhandledError/OnUnhandledException.

    No, that is an approach for OnSuspend method. You could post a user voice to the dev center.

    I wonder this is somehow related with the C++ language, because if I run some similar code via C#, it works.

    Monday, February 22, 2016 2:04 AM