Java Equivalent of C# Async/Await

Java Equivalent of C# async/await?

No, there isn't any equivalent of async/await in Java - or even in C# before v5.

It's a fairly complex language feature to build a state machine behind the scenes.

There's relatively little language support for asynchrony/concurrency in Java, but the java.util.concurrent package contains a lot of useful classes around this. (Not quite equivalent to the Task Parallel Library, but the closest approximation to it.)

Why does Java have no async/await?

The short answer is that the designers of Java try to eliminate the need for asynchronous methods instead of facilitating their use.

According to Ron Pressler's talk asynchronous programming using CompletableFuture causes three main problems.

  1. branching or looping over the results of asynchronous method calls is not possible
  2. stacktraces cannot be used to identify the source of errors, profiling becomes impossible
  3. it is viral: all methods that do asynchronous calls have to be asynchronous as well, i.e. synchronous and asynchronous worlds don't mix

While async/await solves the first problem it can only partially solve the second problem and does not solve the third problem at all (e.g. all methods in C# doing an await have to be marked as async).

But why is asynchronous programming needed at all? Only to prevent the blocking of threads, because threads are expensive. Thus instead of introducing async/await in Java, in project Loom Java designers are working on virtual threads (aka fibers/lightweight threads) which will aim to significantly reduce the cost of threads and thus eliminate the need of asynchronous programming. This would make all three problems above also obsolete.

Is there something like C# Task in Java?

The Fork/Join framework introduced in Java 7 is probably the closest thing:

http://docs.oracle.com/javase/tutorial/essential/concurrency/forkjoin.html

Differences between C# async and Java ExecutorService

No, await is not like just calling get(). There's considerably more to it.

When you use an await expression in C#, the compiler effectively creates a continuation, so that if the awaitable hasn't completed yet, the method can immediately return, and continue processing only when it's completed. The continuation will run in an appropriate context - so if you're on a UI thread before the await expression, you'll continue on the UI thread afterwards, but without blocking the UI thread while you're waiting for the result. For example:

public async void HandleButtonClick(object sender, EventArgs e)
{
// All of this method will run in the UI thread, which it needs
// to as it touches the UI... however, it won't block when it does
// the web operation.

string url = urlTextBox.Text;
WebClient client = new WebClient();
string webText = await client.DownloadStringTaskAsync(url);

// Continuation... automatically called in the UI thread, with appropriate
// context (local variables etc) which we used earlier.
sizeTextBox.Text = string.Format("{0}: {1}", url, webText.Length);
}

Ultimately it's all syntactic sugar, but much more complicated sugar than what you've shown.

There's a lot of detailed information available on the web already. For example:

  • Eric Lippert's blog
  • The Microsoft C# async/await guide
  • My own blog posts about async

Javascript async await equivalent of C# Task.Delay

You could write your own delay method.

function delay(time) {
return new Promise((resolve) => {
setTimeout(() => resolve(), time);
});
}

To use it

async function someMethod(myStr) {
await delay(2000);

// Continue here after 2 secs
}

C# equivalent of Java awaitility

I would do something like

public static async Task WaitForElementAsync(WebElement element)
{
await With(100, 200, true, () => element.isDisplayed());
}

private static async Task With(
int pollDeley,
int pollIntervall,
bool ignoreException,
Func<bool> until)
{
await Task.Delay(pollDeley);

var loop = true;

while (loop)
{
try
{
loop = !until();
if (!loop) break;
await Task.Delay(pollIntervall);
}
catch (Exception ex)
{
if (!ignoreException) throw;
}
}
}

but there might be a better solution if WebElement has an event like IsDisplayedChanged.

Also with this solution you introduce a async call line to your project (which in a web context can be beneficial), to avoid this you can replace the await Task.Delay(...) with Thread.Sleep(...).

Another solution would be to use a timer for the polling

private static async Task With(
int pollDeley,
int pollIntervall,
bool ignoreException,
Func<bool> until)
{
await Task.Delay(pollDeley);

var tcs = new TaskCompletionSource<bool>();

using (var timer = new Timer(pollIntervall))
{
void Poll(object sender, ElapsedEventArgs e)
{
try
{
if (until())
{
if (tcs.TrySetResult(true))
{
timer.Stop();
}
}
}
catch (Exception ex)
{
if (!ignoreException)
{
if (tcs.TrySetException(ex))
{
timer.Stop();
}
}
}
}

timer.Elapsed += Poll;

timer.Start();

await tcs.Task;

timer.Elapsed -= Poll;
}
}


Related Topics



Leave a reply



Submit