boxofyellow / ConsoleMarkdownRenderer

Library for rendering markdown within the console
https://www.nuget.org/packages/BoxOfYellow.ConsoleMarkdownRenderer
MIT License
2 stars 0 forks source link

Deadlock when calling DisplayMarkdown repeatedly #10

Open raffaeler opened 1 month ago

raffaeler commented 1 month ago

Describe the bug I am in an ASP.NET app (.NET 8.0). The call is straightforward:

Displayer.DisplayMarkdown(content, new Uri("about:blank"));

When the method containing (only) the above method is called repeatedly, the code has a deadlock

The deadlock stack is the following:

Not Flagged     8372    15  Worker Thread   .NET TP Worker  System.Private.CoreLib.dll!System.Threading.Monitor.Wait
System.Private.CoreLib.dll!System.Threading.Monitor.Wait(object obj, int millisecondsTimeout) Line 156
System.Private.CoreLib.dll!System.Threading.ManualResetEventSlim.Wait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) Line 561
System.Private.CoreLib.dll!System.Threading.Tasks.Task.SpinThenBlockingWait(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) Line 3072
System.Private.CoreLib.dll!System.Threading.Tasks.Task.InternalWaitCore(int millisecondsTimeout, System.Threading.CancellationToken cancellationToken) Line 3007
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(System.Threading.Tasks.Task task, System.Threading.Tasks.ConfigureAwaitOptions options) Line 104
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter<int>.GetResult() Line 335
[Waiting on Async Operation, double-click or press enter to view Async Call Stacks]
Spectre.Console.dll!Spectre.Console.SelectionPrompt<int>.Show(Spectre.Console.IAnsiConsole console) Line 94
Spectre.Console.dll!Spectre.Console.AnsiConsole.Prompt<int>(Spectre.Console.IPrompt<int> prompt) Line 21
ConsoleMarkdownRenderer.dll!ConsoleMarkdownRenderer.Displayer.DisplayMarkdown(string text, System.Uri baseUri, ConsoleMarkdownRenderer.DisplayOptions options, bool allowFollowingLinks, ConsoleMarkdownRenderer.ObjectRenderers.TempFileManager tempFiles) Line 151
ConsoleMarkdownRenderer.dll!ConsoleMarkdownRenderer.Displayer.DisplayMarkdown(string text, System.Uri baseUri, ConsoleMarkdownRenderer.DisplayOptions options, bool allowFollowingLinks) Line 61
FormattedLogger.dll!FormattedLogger.Writers.MarkdownConsoleWriter.Print(string content) Line 19
FormattedLogger.dll!FormattedLogger.Writers.MarkdownConsoleWriter.WriteLine(string content) Line 24
FormattedLogger.dll!FormattedLogger.SessionLogger.Write(string content) Line 50
GenAIExplorer.dll!GenAIExplorer.CompletionHub.PrepareCompletion(GenAIExplorer.SettingsAndPrompts settingsAndPrompts, AICommon.Scenarios.Inquiry inquiry, bool restrictToMyData, FormattedLogger.SessionLogger logger, AICommon.Helpers.PromptHelper promptHelper) Line 175
GenAIExplorer.dll!GenAIExplorer.CompletionHub.SendSettingsAndPromptsStreaming(GenAIExplorer.SettingsAndPrompts settingsAndPrompts) Line 306
[Resuming Async Method]
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 179
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.AsyncStateMachineBox<GenAIExplorer.CompletionHub.<SendSettingsAndPromptsStreaming>d__18>.MoveNext(System.Threading.Thread threadPoolThread) Line 368
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__12_0(System.Action innerContinuation, System.Threading.Tasks.Task innerTask) Line 273
System.Private.CoreLib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining) Line 743
System.Private.CoreLib.dll!System.Threading.Tasks.Task.RunContinuations(object continuationObject) Line 3462
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult() Line 109
[Completed] FormattedLogger.dll!FormattedLogger.SessionLogger.Write(string content) Line 52
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 179
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.AsyncStateMachineBox<FormattedLogger.SessionLogger.<Write>d__17>.MoveNext(System.Threading.Thread threadPoolThread) Line 368
System.Private.CoreLib.dll!System.Runtime.CompilerServices.TaskAwaiter.OutputWaitEtwEvents.AnonymousMethod__12_0(System.Action innerContinuation, System.Threading.Tasks.Task innerTask) Line 273
System.Private.CoreLib.dll!System.Threading.Tasks.AwaitTaskContinuation.RunOrScheduleAction(System.Action action, bool allowInlining) Line 743
System.Private.CoreLib.dll!System.Threading.Tasks.Task.RunContinuations(object continuationObject) Line 3462
System.Private.CoreLib.dll!System.Threading.Tasks.Task<System.Threading.Tasks.VoidTaskResult>.TrySetResult(System.Threading.Tasks.VoidTaskResult result) Line 398
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.SetExistingTaskResult(System.Threading.Tasks.Task<System.Threading.Tasks.VoidTaskResult> task, System.Threading.Tasks.VoidTaskResult result) Line 490
[Completed] System.Private.CoreLib.dll!System.IO.File.WriteToFileAsync(string path, System.IO.FileMode mode, string contents, System.Text.Encoding encoding, System.Threading.CancellationToken cancellationToken) Line 1313
System.Private.CoreLib.dll!System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(System.Threading.Thread threadPoolThread, System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) Line 264
System.Private.CoreLib.dll!System.Runtime.CompilerServices.AsyncTaskMethodBuilder<System.Threading.Tasks.VoidTaskResult>.AsyncStateMachineBox<System.IO.File.<WriteToFileAsync>d__108>.MoveNext(System.Threading.Thread threadPoolThread) Line 372
System.Private.CoreLib.dll!System.Threading.ThreadPoolWorkQueue.Dispatch() Line 913
System.Private.CoreLib.dll!System.Threading.PortableThreadPool.WorkerThread.WorkerThreadStart() Line 102

Expected behavior I expect to never get a deadlock, even in case of concurrent threadin (which is not happening here)

please include the following