0

I need this function to run Async, but can't seem to figure a way to do it.

LIST1 is Public and contains a List(of String) with a few hundred entries. List Declaration:

Public LIST1 As New List(Of String)

Normally, I'd run the following code to retrieve the boolean of whether or not he list contains the entry:

Dim result = LIST1.Any(Function(s) value.ToLower.Contains(s))

Full non-Async function:

Function CheckValue(byval value As String) As Boolean
    Dim result As Boolean = LIST1.Any(Function(s) value.ToLower.Contains(s))
    Return result
End Function

That works well as expected.

How would I implement the same as an Async function? I've tried:

Async Function CheckValue(byval value as String) As Task(Of Boolean)
    Dim result as Task(Of Boolean) = Await LIST1.Any(Function(s) value.ToLower.Contains(s))
    Return result
End Function

I get the following error: 'Await' requires that the type 'Boolean' have a suitable GetAwaiter method.

Any thoughts?

nukalov
  • 1,309
  • 13
  • 18
  • `Any()` is not async. You cannot make it to be async. It does not make sense to create an async wrapper for it either because it's not IO-bound. – GSerg Apr 05 '19 at 18:39
  • 2
    You want to [use `Task.Run`](https://stackoverflow.com/a/28071880/11683) or [`AsParallel.Any`](https://stackoverflow.com/q/25379025/11683). – GSerg Apr 05 '19 at 18:47
  • 3
    Consider eliminating superfluous string allocations. Instead of `value.ToLower.Contains(s)` (`ToLower` creates a new string), use `value.IndexOf(s, StringComparison.CurrentCultureIgnoreCase) > 0`. – TnTinMn Apr 05 '19 at 19:20

1 Answers1

2

It does not return a task, so there is no reason to await it. If your concern is that it is too slow, you can run any synchronous code in a new thread, and then await the completion of that thread, like this:

Dim result As Boolean = Await Task.Run(Function() LIST1.Any(Function(s) value.ToLower.Contains(s)))

Or, as GSerg mentioned, though it technically doesn't make it awaitable, you can use AsParallel.Any:

Dim result As Boolean = LIST1.AsParallel.Any(Function(s) value.ToLower.Contains(s))

However, be aware that starting new threads has a fair amount of overhead, so starting up a new thread, just to do a small amount of work, may make it actually run slower.

In this particular case, if performance is key, I would recommend looking into various search/indexing algorithms. For instance, take a look at some of the ones mentioned here. I wouldn't be surprised if there are opensource .NET libraries for those kinds of algorithms.

Steven Doggart
  • 43,358
  • 8
  • 68
  • 105