Answered by:
Create an IBuffer to use with StreamSocket::OutputStream::WriteAsync

Question
-
Hi,
How can it create an IBuffer to use with StreamSocket::OutputStream::WriteAsyncI, i have the data i want to send in a byte array, but don't know what will be the efficient way to pass this data to WriteAsync.
Regards,
Jose
Tuesday, May 8, 2012 3:17 PM
Answers
-
From your code
DataWriterStoreOperation^ store_data = nullptr; store_data = writer_ >StoreAsync(); AsyncStatus storestarus = store_data->Status; while (storestarus != AsyncStatus::Completed) { WaitForSingleObjectEx(_socket->smi_event_wait,2,false); //event control wait time 2 = 2ms storestarus = store_data->Status; // here you should set wait time out to protect it can't return and blocked return; }
Seems to me that will be better to avoid while loop and use the Completed handler.
DataWriterStoreOperation^ writerResult = writer->StoreAsync(); writerResult->Completed = ref new AsyncOperationCompletedHandler<unsigned int>( [=](IAsyncOperation<unsigned int>^ info, Windows::Foundation::AsyncStatus status) { if(info->Status == Windows::Foundation::AsyncStatus::Error) { // Error } else if(info->Status == Windows::Foundation::AsyncStatus::Canceled) { // Canceled } else if(info->Status == Windows::Foundation::AsyncStatus::Completed) { // Success } });
- Proposed as answer by Jesse Jiang Friday, May 18, 2012 8:15 AM
- Marked as answer by pepone.onrez Friday, May 18, 2012 2:46 PM
Wednesday, May 16, 2012 4:47 PM
All replies
-
Hi ,I use this code to do send data ,you can see it.
before you send data, you should make sure the connect is completed and successfully.
StreamSocket^ socket = ref new StreamSocket(); IOutputStream^ senddata = socket->OutputStream; DatDataWriter^ writer_ = ref new DataWriter(senddata); auto data = ref new Platform::Array<unsigned char>(size); ::memcpy(data->Data, buf, size);//buf is char* style ( your data ) auto task1 = make_task([=] { try { DataWriterStoreOperation^ store_data = nullptr; store_data = writer_ >StoreAsync(); AsyncStatus storestarus = store_data->Status; while (storestarus != AsyncStatus::Completed) { WaitForSingleObjectEx(_socket->smi_event_wait,2,false);//event control wait time 2 = 2ms storestarus = store_data->Status;
// here you should set wait time out to protect it can't return and blocked return; } } catch (Exception^ e) { return; } }); structured_task_group tasks; tasks.run_and_wait(task1);
- Edited by oishixixi Wednesday, May 9, 2012 6:01 AM
- Marked as answer by pepone.onrez Wednesday, May 9, 2012 9:36 AM
- Unmarked as answer by pepone.onrez Wednesday, May 9, 2012 10:29 AM
Wednesday, May 9, 2012 5:44 AM -
Hi,
After looked closer at the proposed solution i unmarked it as answer, i want to avoid the memcpy, as this is expensive operation.
Will something along this lines work?
Does it create an extra copy of the data? if so how can i avoid the extra copy?
unsinged char* data = new char[SIZE]; // Filled some where in the code. void write(unsigned char* data) { DataWriter writer = ref new DataWriter(); writer->WriteBytes(ref new Array<unsigned char>(data, SIZE)); _socket->OutputStream->WriteAsync(write->DetachBuffer()); }
Regards,
Jose
Wednesday, May 9, 2012 10:36 AM -
I use memcpy() because I use the buffer is char* type.
If you use data type is defined by metro api , like IBuffer^ ,array<unsigned char>^ and so on,
you needn't use memcpy(); it's just an example.
Monday, May 14, 2012 10:01 AM -
I know is an example, i just was asking if there is a way that IBuffer can use the char* buffer without copy it, an IBuffer implementation that directly writes to the char* C style buffer.
From my experiments with Platform::Array, when you pass the data, and size arguments the array ctor copy the data, so not need to explicit copy it with memcpy.
auto data = ref new Platform::Array<unsigned char>(size); ::memcpy(data->Data, buf, size);//buf is char* style ( your data )
Will be the same as
auto data = ref new Platform::Array<unsigned char>(buf, size);
Also not sure if will be faster to use memcpy or pass the data.
- Edited by pepone.onrez Wednesday, May 16, 2012 4:36 PM
Wednesday, May 16, 2012 4:36 PM -
From your code
DataWriterStoreOperation^ store_data = nullptr; store_data = writer_ >StoreAsync(); AsyncStatus storestarus = store_data->Status; while (storestarus != AsyncStatus::Completed) { WaitForSingleObjectEx(_socket->smi_event_wait,2,false); //event control wait time 2 = 2ms storestarus = store_data->Status; // here you should set wait time out to protect it can't return and blocked return; }
Seems to me that will be better to avoid while loop and use the Completed handler.
DataWriterStoreOperation^ writerResult = writer->StoreAsync(); writerResult->Completed = ref new AsyncOperationCompletedHandler<unsigned int>( [=](IAsyncOperation<unsigned int>^ info, Windows::Foundation::AsyncStatus status) { if(info->Status == Windows::Foundation::AsyncStatus::Error) { // Error } else if(info->Status == Windows::Foundation::AsyncStatus::Canceled) { // Canceled } else if(info->Status == Windows::Foundation::AsyncStatus::Completed) { // Success } });
- Proposed as answer by Jesse Jiang Friday, May 18, 2012 8:15 AM
- Marked as answer by pepone.onrez Friday, May 18, 2012 2:46 PM
Wednesday, May 16, 2012 4:47 PM -
Yes you code is safer, and you maybe try to find a way that IBuffer can use the char* buffer without copy it.
if you succeed, hope you submit it to here and share it .
thank you
- Marked as answer by pepone.onrez Friday, May 18, 2012 2:46 PM
- Unmarked as answer by pepone.onrez Friday, May 18, 2012 2:46 PM
Friday, May 18, 2012 2:30 AM -
Yes i will look at this later, and i will update this thread if i found how that can be done. Thanks for the help and for take the time to look at this.Friday, May 18, 2012 2:47 PM