locked
Task and Files question

    Question

  • Hello,

    my code fails. why ?

    void BlankApp1::MainPage::btnCreateWrite_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
        this->txtFileBox->Text = "Create";

        IAsyncOperation<StorageFile ^> ^ op = KnownFolders::PicturesLibrary->CreateFileAsync("text1.txt", CreationCollisionOption::ReplaceExisting);
        auto task1 = create_task(op);
        task1.wait();
        this->m_file = op->GetResults();

        if (this->m_file == nullptr)
        {
            this->txtFileBox->Text = "m_file is nullptr";
            return;
        }

        this->txtFileBox->Text = "WriteFile";
        String ^ name = m_file->Name;

        IAsyncAction ^ action = FileIO::WriteTextAsync(m_file, "hello world");
        auto task2 = create_task(action);
        task2.wait();

        this->txtFileBox->Text = "Create & WriteFile";
    }


    Christophe Pichaud

    Saturday, December 28, 2013 8:16 PM

Answers

All replies

  • In what way does it fail?

    One suspicious bit is calling Task.Wait on the UI thread. That will raise an exception. Instead use PPL to have your code called after the task completes. See Asynchronous programming in C++

    --Rob

    Saturday, December 28, 2013 8:45 PM
    Moderator
  • Here is my code which works for saving a game state.

    			 void Renderer::savegame()
    			 {
    
    		Platform::String^ fileName="arnold.pcb";
    		
    
    		
    create_task(KnownFolders::PicturesLibrary->CreateFileAsync(fileName, CreationCollisionOption::ReplaceExisting)).then([this](StorageFile^ file)
    {
    	auto openOp = file->OpenAsync (FileAccessMode::ReadWrite);
        openOp->Completed = 
          ref new AsyncOperationCompletedHandler <IRandomAccessStream^>
          ([=](IAsyncOperation<IRandomAccessStream^>^ operation, AsyncStatus status)
        {
    		auto istream = operation->GetResults();
          auto dr = ref new DataWriter(istream);
          
    	
    
    			(dr->WriteUInt32(time));
    			(dr->WriteUInt32(screennumber));
    
    
    
    
    			 create_task(dr->StoreAsync()).then([this,dr](UINT16 bytesWritten)
                    {
    					
    			 });
    
    			
    			
    
            
          });
        });
    			 }
    
    


    n.Wright

    • Proposed as answer by nigelwright7557 Saturday, December 28, 2013 10:24 PM
    Saturday, December 28, 2013 10:23 PM
  • you are right. It raises a throw invalid_operation("Illegal to wait on a task in a Windows Runtime STA");

    my first goal was to decompose the create_task mecanism. I need to use the orginal create_task & then idom

    thannks.


    Christophe Pichaud

    Sunday, December 29, 2013 10:30 AM
  • Here is the good code:

    void BlankApp1::MainPage::btnCreateWrite_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e)
    {
    	this->txtFileBox->Text = "Create";
    
    	IAsyncOperation<StorageFile ^> ^ op = KnownFolders::PicturesLibrary->CreateFileAsync("text1.txt", CreationCollisionOption::ReplaceExisting);
    	auto task1 = create_task(op);
    	task1.then([this](StorageFile ^ file) 
    	{
    		this->m_file = file;
    		String ^ name = m_file->Name;
    
    		IAsyncAction ^ action = FileIO::WriteTextAsync(m_file, "hello world");
    		auto task2 = create_task(action).then([this](task<void> task) 
    		{
    			task.get();
    		});
    	});
    
    
    	this->txtFileBox->Text = "Create & WriteFile";
    }
    
    
    Christophe Pichaud
    Sunday, December 29, 2013 3:11 PM