Reputation: 123
Is there a way to use the Task-based Asynchronous Pattern (TAP) in .NET 4.0 without the await
and async
keywords? (I ask because we are stuck in C# 4.0.)
Also, is there an example of using TAP with WCF with .NET 4.0?
Upvotes: 9
Views: 9990
Reputation: 61666
Is there a way to use Task-based Asynchronous Pattern (TAP) in .NET 4.0 without the keyword await or async? I ask because we are stuck in C#4)
One notable and handy hack is to use yield
and IEnumerable<Task>
. E.g., from Stephen Toub's "Processing Sequences of Asynchronous Operations with Tasks":
IEnumerable<Task> DoExample(string input)
{
var aResult = DoAAsync(input);
yield return aResult;
var bResult = DoBAsync(aResult.Result);
yield return bResult;
var cResult = DoCAsync(bResult.Result);
yield return cResult;
…
}
…
Task t = Iterate(DoExample(“42”));
This way, you can have a pseudo-synchronous linear code flow similar to async/await
.
Upvotes: 5
Reputation: 23833
Yes you can. The TAP is just a sensible formalization of best practice when working with asynchronous code. Basically a TAP method
Task
or Task<TResult>
.SomeMethodAsync(...)
).So, an example might be
private Task SomeMethodAsync(CancellationToken token)
{
return Task.Factory.StartNew(() =>
{
// Do something...
}, token);
}
use the method and attach continuation which uses the UI synchronization context.
private void SomeOtherMethod()
{
var tokenSource = new CancellationTokenSource();
CancellationToken token = tokenSource.Token;
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext()
// Options 1.
Task t = SomeMethodAsync(token);
Task c = t.ContinueWith(ant =>
{
/* Do something and check exceptions */
}, CancellationToken.None,
TaskContinuationOptions.None,
scheduler);
// Options 2.
SomeMethodAsync(token).ContinueWith(ant =>
{
/* Do something and check exceptions */
}, CancellationToken.None,
TaskContinuationOptions.None,
scheduler);
}
Or do it all in one go
Task t = Task.Factory.StartNew(() =>
{
/* Do Something */
}, token).ContinueWith(ant =>
{
/* Do something on UI thread after task has completed and check exceptions */
}, CancellationToken.None,
TaskContinuationOptions.None,
scheduler);
You can also implement the TAP pattern manually for better control over implementation. To implement the TAP yourself, you create a TaskCompletionSource<TResult>
object, perform the asynchronous operation, and when it completes, call the SetResult
, SetException
, or SetCanceled
method, or the Try
version of one of these methods. When you implement a TAP method manually, you must complete the resulting task when the represented asynchronous operation completes. For example:
public static Task<int> ReadTask(this Stream stream,
byte[] buffer, int offset, int count, object state)
{
var tcs = new TaskCompletionSource<int>();
stream.BeginRead(buffer, offset, count, ar =>
{
try { tcs.SetResult(stream.EndRead(ar)); }
catch (Exception exc) { tcs.SetException(exc); }
}, state);
return tcs.Task;
}
Consume the TaskCompleationSource
from the consumer.
I hope this helps.
Upvotes: 10
Reputation: 464
yeah there is. Async Wrappers for "Begin/End" methods comes to my mind;
public static Task<WebResponse> GetResponseAsync(this WebRequest client)
{
return Task<WebResponse>.Factory.FromAsync(client.BeginGetResponse,
client.EndGetResponse, null);
}
i guess what you are looking for Implement a WCF Asynchronous Service Operation with Task
Upvotes: 0
Reputation: 116118
You don't need async/await. The keywords can be
ContinueWith
and TaskScheduler.FromCurrentSynchronizationContext
Task.Factory.StartNew(() => { return "test"; } )
.ContinueWith(task => { this.textBox1.Text = task.Result; },
CancellationToken.None,
TaskContinuationOptions.None,
TaskScheduler.FromCurrentSynchronizationContext());
This is roughly equal to
var str = await SomeFuncAsync() //returning "test";
this.textBox1.Text = str;
Upvotes: 8
Reputation: 3268
Without the async/await keywords you won't be able to utilize the easiness provided by compiler to use the new pattern. However you can leverage Task based parallelism using Task Parallel Library (TPL) in .NET 4 framework
Upvotes: 0