Introduction: The Problem with LLM Latency

LLMs generate responses token by token, producing output one character or word at a time. For complex questions, such as comparing electric guitar models in terms of sound, feel and use across different music genres, the AI needs more time to generate its response. When an application blocks and waits for the model to finish before displaying anything, users often see only a loading screen for several seconds. This gap leads to a less satisfying user experience because the system lacks visual feedback that it is processing.

The Standard Way: RunAsync (Blocking)

The standard Microsoft Agent approach uses await agent.RunAsync("Your question"). With this method, the program execution pauses and waits until the AI has fully generated its response before continuing. You get a response object, from which you extract the text using .ToString() or by writing the object to the console. The response object also includes helpful metadata, like exact token usage (input and output tokens) for the request.

var response = await agent.RunAsync("Which guitar brands are most popular for rock and blues?");
Console.WriteLine(response); // Automatically extracts and prints the final text

The interface remains frozen until the answer completes.

The Interactive Solution: RunStreamingAsync (Real-Time Feedback)

To avoid long waiting times, you can use agent.RunStreamingAsync(“Your question”). This method streams generated text pieces asynchronously rather than waiting for the full response. Use an await foreach loop to handle these updates. Each update adds newly generated characters.

await foreach (var update in agent.RunStreamingAsync("Explain how Gibson and Fender guitars differ in sound, feel, and typical use cases."))
{
    Console.Write(update);
}

Console.Write(update) builds text live on the screen.

The response types out word by word.

The user sees progress immediately and can start reading, rather than waiting for the entire generation process to finish.

Practical Comparison: When to use what?

When RunStreamingAsync shines:

This method is recommended for chatbots and UI integrations (such as console applications, Blazor WebAssembly, or React frontends) where people interact directly with the system. When a user waits for long text, streaming is essential for a good experience.

When RunAsync is the better choice:

For automated background processes (such as background jobs, webhooks, schedules, or email processing), streaming doesn’t matter because nobody is watching live. RunAsync is best when you request Structured Output (JSON/C # objects) using the RunAsync<T> method. You cannot deserialize an incomplete JSON file. So, there is no reason to stream when you need the fully formed object to process it further.

Conclusion

RunAsync delivers the full response at once, while RunStreamingAsync streams it live and dynamically. By understanding both methods, you gain the foundational knowledge required for AI communication in C#.

Our agent replies in real time, but still forgets prior info like your name. Next, we’ll solve this by exploring chat history and memory management.

Further Reading