This could be as simple as a web server firing off a new green thread or a goroutine for an incoming request, or as contrived as doing so manually within a function scope.
In practice, there really is not much difference with async/await. "Green threads" is a combination of implementation details and a subset of what async/await abstractions achieve.
Effectively, Goroutines are in many ways similar to C# Task<T>s. The difference is that in Go you are expected to explicitly send the result via a channel or some other data structure and then synchronize the completion of the execution, where-as with tasks you simply await that.
There could be an argument made about preference of implicit suspend (Go, Java, BEAM family) over explicit suspend (C#/F#, Rust, JS, Python, C++ co_await, Swift), but for practical purposes invoking a function with 'go' keyword in Golang is very similar to firing off a synchronous method with Task.Run in C#, or calling an asynchronous method (with sufficiently short body before first yield) and not immediately awaiting it.
As I usually post it on HN, tasks make the following patterns trivial:
using var http = new HttpClient {
BaseAddress = new("https://news.ycombinator.com/")
};
// not immediately awaited requests are executed in parallel
var frontPage = http.GetStringAsync("news?p=1");
var secondPage = http.GetStringAsync("news?p=2");
Console.WriteLine($"{await frontPage}\n\n{await secondPage}");