Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Working with System.Threading.Tasks.Task<Stream> instead of Stream

I was using a method like below on the previous versions of WCF Web API:

// grab the posted stream
Stream stream = request.Content.ContentReadStream;

// write it to   
using (FileStream fileStream = File.Create(fullFileName, (int)stream.Length)) {

    byte[] bytesInStream = new byte[stream.Length];
    stream.Read(bytesInStream, 0, (int)bytesInStream.Length);
    fileStream.Write(bytesInStream, 0, bytesInStream.Length);
}

But on the preview 6, HttpRequestMessage.Content.ContentReadStream property is gone. I believe that it now should look like this one:

// grab the posted stream
System.Threading.Tasks.Task<Stream> stream = request.Content.ReadAsStreamAsync();

But I couldn't figure out what the rest of the code should be like inside the using statement. Can anyone provide me a way of doing it?

like image 629
tugberk Avatar asked Dec 06 '11 12:12

tugberk


People also ask

What is using system threading tasks?

Provides types that simplify the work of writing concurrent and asynchronous code. The main types are Task which represents an asynchronous operation that can be waited on and cancelled, and Task<TResult>, which is a task that can return a value.

Which threading Task method will create a Task that will complete when any of the associated tasks have completed?

Wait method. A call to the Wait method blocks the calling thread until the single class instance has completed execution. The following example calls the parameterless Wait() method to wait unconditionally until a task completes. The task simulates work by calling the Thread.

What is the difference Task and thread?

Differences Between Task And ThreadThe Thread class is used for creating and manipulating a thread in Windows. A Task represents some asynchronous operation and is part of the Task Parallel Library, a set of APIs for running tasks asynchronously and in parallel. The task can return a result.

Does Task run block thread?

Run is misused to run IO blocking tasks. Although the code will work just fine (e.g UI not not freeze) but it is still a wrong approach. This is because Task. Run will still block a thread from thread pool the entire time until it finishes the method.


2 Answers

You might have to adjust this depending on what code is happening before/after, and there's no error handling, but something like this:

Task task = request.Content.ReadAsStreamAsync().ContinueWith(t =>
{
    var stream = t.Result;
    using (FileStream fileStream = File.Create(fullFileName, (int) stream.Length)) 
    {
        byte[] bytesInStream = new byte[stream.Length];
        stream.Read(bytesInStream, 0, (int) bytesInStream.Length);
        fileStream.Write(bytesInStream, 0, bytesInStream.Length);
    }
});

If, later in your code, you need to ensure that this has completed, you can call task.Wait() and it will block until this has completed (or thrown an exception).

I highly recommend Stephen Toub's Patterns of Parallel Programming to get up to speed on some of the new async patterns (tasks, data parallelism etc) in .NET 4.

like image 80
Jon Avatar answered Oct 30 '22 11:10

Jon


Quick and dirty fix:

// grab the posted stream
Task<Stream> streamTask = request.Content.ReadAsStreamAsync();
Stream stream = streamTask.Result; //blocks until Task is completed

Be aware that the fact that the sync version has been removed from the API suggests that you should really be attempting to learn the new async paradigms to avoid gobbling up many threads under high load.

You could for instance:

streamTask.ContinueWith( _ => {
    var stream = streamTask.Result; //result already available, so no blocking
    //work with stream here
} )

or with new async await features:

//async wait until task is complete
var stream = await request.Content.ReadAsStreamAsync(); 

Take time to learn async/await. It's pretty handy.

like image 24
spender Avatar answered Oct 30 '22 10:10

spender