locked
[UWP][C++]Serveral questions about DataWriter/DataReader and the associated I/O model RRS feed

  • Question

  • I'm using C++/CX in my UWP projects.

    From the DataReaderWriter sample, it says we should detachStream() before the DataWriter object die in order to keep the stream from being closed. But in other DataWriter/DataReader sample codes, I didn't find more evidence which suggest this is a requirement, and the docs don't mention anything more details. My question is, when should we detachStream()? For example, if a StreamSocket object outlive the DataWriter object, do I have to detachStream()? Or is this only required when there is no other references holding the life of the underlying stream object?

    Second question about DataWriter/DataReader: After we call StoreAsync/LoadAsync in thread A, can we continue call WriteXXX/ReadXXX in thread A without block waiting for the Store/Load complete? 

    Third, when use StoreAsync() with creat_task() and .then(), is it possible that within the completion continuation, only partial bytes(from the buffer) are stored AND without exceptions thrown? If so, how to handle this kind of partial bytes stored scenario? Do I have to StoreAsync() the left bytes again?

    All three questions are not well document afaik. Help please.


    • Edited by JC Yang Tuesday, June 21, 2016 1:53 AM
    Tuesday, June 21, 2016 1:50 AM

Answers

  • Hi JC Yang,

    >>does it mean the detachStream() can be omitted in the very sample and all C++/CX codes?And why Dispose() and detachStream() are related?
    The Dispose() method is to releasing or resetting unmanaged resources. If the DataWriter has not released or resetted, we can use the detachStream() method. The Dispose() and detachStream() are not related. I use it to explain the detachStream() can not work after it disposed.
    >>So for StoreAsync()/LoadAsync(), the result task<unsigned int> is only for us to capture any exceptions thrown?
    No, it isn't. When we use the async method, we need wait the async method to complete. You can see Asynchronous programming in C++: https://msdn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-in-cpp-universal-windows-platform-apps

    Best Regards,
    Jayden Gu


    • Proposed as answer by Jayden Gu Thursday, June 30, 2016 8:41 AM
    • Marked as answer by Barry Wang Friday, July 1, 2016 2:03 AM
    Friday, June 24, 2016 10:04 AM

All replies

  • Are the answers of these questions really unknown? Not even the MS guys?
    Tuesday, June 21, 2016 11:53 PM
  • Hi JC Yang,
    >>My question is, when should we detachStream()? For example, if a StreamSocket object outlive the DataWriter object, do I have to detachStream()? Or is this only required when there is no other references holding the life of the underlying stream object?
    In the Sample comments: In order to prolong the lifetime of the stream, detach it from the DataWriter so that it will not be closed when the dataWriter is destructed. We were to fail to detach the stream, the dataWriter destructor would close the underlying stream, preventing its subsequent use by the DataReader below.
    If you do not run the Dispose() method of the DataWriter, we can remove the detachStream() method;
    >>After we call StoreAsync/LoadAsync in thread A, can we continue call WriteXXX/ReadXXX in thread A without block waiting for the Store/Load complete? 
    You should able to add creat_task() and .then operator for the  async method. That make sure the StoreAsync/LoadAsync method has completed.
    >>Third, when use  StoreAsync() with creat_task() and .then(), is it possible that within the completion continuation, only partial bytes(from the buffer) are stored AND without exceptions thrown? If so, how to handle this kind of partial bytes stored scenario? Do I have to StoreAsync() the left bytes again?
    When we use StoreAsync() with creat_task() and .then(), it will wait for the StoreAsync() to finish. So we do not need to worry about this.
    Best Regards,


    Jayden Gu

    Wednesday, June 22, 2016 1:50 PM
  • In the Sample comments: In order to prolong the lifetime of the stream, detach it from the DataWriter so that it will not be closed when the dataWriter is destructed. We were to fail to detach the stream, the dataWriter destructor would close the underlying stream, preventing its subsequent use by the DataReader below.
    If you do not run the Dispose() method of the DataWriter, we can remove the detachStream() method;

    In the very sample, no Dispose() are called, and from both the documents and code test(IDE suggest no such member), Dispose() is not a method exposed to C++/CX ABI, does it mean the detachStream() can be omitted in the very sample and all C++/CX codes?

    And why Dispose() and detachStream() are related?

    >>After we call StoreAsync/LoadAsync in thread A, can we continue call WriteXXX/ReadXXX in thread A without block waiting for the Store/Load complete? 
    You should able to add creat_task() and .then operator for the  async method. That make sure the StoreAsync/LoadAsync method has completed.

    Yes, I know we should use create_task() and .then(), and I do use them. I think codes sample can better clarify my question.

    auto writer = ref new DataWriter(stream);
    writer->WriteBytes(some_bins);
    create_task(writer->StoreAsync()).then([writer](task<unsigned int> bytesWritten){... some continuation works...});
    
    writer->WriteBytes(new_bins); // no block waiting for the StoreAsync complete, is this a valid usage?


    >>Third, when use  StoreAsync() with creat_task() and .then(), is it possible that within the completion continuation, only partial bytes(from the buffer) are stored AND without exceptions thrown? If so, how to handle this kind of partial bytes stored scenario? Do I have to StoreAsync() the left bytes again?
    When we use StoreAsync() with creat_task() and .then(), it will wait for the StoreAsync() to finish. So we do not need to worry about this.

    So for StoreAsync()/LoadAsync(), the result task<unsigned int> is only for us to capture any exceptions thrown?




    • Edited by JC Yang Thursday, June 23, 2016 1:32 AM format
    Thursday, June 23, 2016 1:29 AM
  • Hi JC Yang,

    >>does it mean the detachStream() can be omitted in the very sample and all C++/CX codes?And why Dispose() and detachStream() are related?
    The Dispose() method is to releasing or resetting unmanaged resources. If the DataWriter has not released or resetted, we can use the detachStream() method. The Dispose() and detachStream() are not related. I use it to explain the detachStream() can not work after it disposed.
    >>So for StoreAsync()/LoadAsync(), the result task<unsigned int> is only for us to capture any exceptions thrown?
    No, it isn't. When we use the async method, we need wait the async method to complete. You can see Asynchronous programming in C++: https://msdn.microsoft.com/en-us/windows/uwp/threading-async/asynchronous-programming-in-cpp-universal-windows-platform-apps

    Best Regards,
    Jayden Gu


    • Proposed as answer by Jayden Gu Thursday, June 30, 2016 8:41 AM
    • Marked as answer by Barry Wang Friday, July 1, 2016 2:03 AM
    Friday, June 24, 2016 10:04 AM