<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Nbrave51</title>
        <link>https://paragraph.com/@nbrave51</link>
        <description>Hi,Web3!</description>
        <lastBuildDate>Thu, 03 Sep 2026 08:25:48 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <image>
            <title>Nbrave51</title>
            <url>https://storage.googleapis.com/papyrus_images/9bc531bffb530b4b78510301e40b68d6583b414e45082f561c5c075996e1cb59.jpg</url>
            <link>https://paragraph.com/@nbrave51</link>
        </image>
        <copyright>All rights reserved</copyright>
        <item>
            <title><![CDATA[VB.NET中async函数调用时使用await与.result的区别]]></title>
            <link>https://paragraph.com/@nbrave51/vb-net-async-await-result</link>
            <guid>lkdONy8IMKHizt8BKMVF</guid>
            <pubDate>Thu, 27 Jun 2024 03:30:59 GMT</pubDate>
            <description><![CDATA[最近写的一个async函数： Public Async Function AfterFirstChat(ByVal strSendMessage As String) As Task(Of String) Try If strSendMessage = "" Then strModOllAmaErrString = STRcurErrHead &#x26; "没有提供要发送的message。" Return "" End If Dim builder As New StringBuilder ' Create a new PromptExecutionSettings object Dim executionSettings As New OpenAIPromptExecutionSettings() ' User question &#x26; answer loop Chat.AddUserMessage(strSendMessage) builder.Clear() ' Get the AI response streamed back to the console Dim...]]></description>
            <content:encoded><![CDATA[<p>最近写的一个async函数：</p><pre data-type="codeBlock" text="    Public Async Function AfterFirstChat(ByVal strSendMessage As String) As Task(Of String)
      
        Try
            If strSendMessage = &quot;&quot; Then
                strModOllAmaErrString = STRcurErrHead &amp; &quot;没有提供要发送的message。&quot;
                Return &quot;&quot;
            End If
            Dim builder As New StringBuilder

            &apos; Create a new PromptExecutionSettings object
            Dim executionSettings As New OpenAIPromptExecutionSettings()

            &apos; User question &amp; answer loop
            Chat.AddUserMessage(strSendMessage)

            builder.Clear()

            &apos; Get the AI response streamed back to the console
            Dim asyncEnumerator As IAsyncEnumerator(Of StreamingChatMessageContent) = Ai.GetStreamingChatMessageContentsAsync(Chat, executionSettings, kKernel).GetAsyncEnumerator()
            Try
                While Await asyncEnumerator.MoveNextAsync()

                    Try
                        Dim message As StreamingChatMessageContent = asyncEnumerator.Current
                        builder.Append(message.Content)

                    Catch ex As Exception

                    End Try
                End While

            Catch ex As Exception

            End Try

            Chat.AddAssistantMessage(builder.ToString())
            Return builder.ToString()
        Catch ex As Exception

            Return &quot;&quot;
        End Try
    End Function
"><code>    <span class="hljs-keyword">Public</span> <span class="hljs-keyword">Async</span> <span class="hljs-keyword">Function</span> AfterFirstChat(<span class="hljs-keyword">ByVal</span> strSendMessage <span class="hljs-keyword">As</span> <span class="hljs-type">String</span>) <span class="hljs-keyword">As</span> Task(<span class="hljs-keyword">Of</span> <span class="hljs-type">String</span>)
      
        <span class="hljs-keyword">Try</span>
            <span class="hljs-keyword">If</span> strSendMessage = <span class="hljs-string">""</span> <span class="hljs-keyword">Then</span>
                strModOllAmaErrString = STRcurErrHead &#x26; <span class="hljs-string">"没有提供要发送的message。"</span>
                <span class="hljs-keyword">Return</span> <span class="hljs-string">""</span>
            <span class="hljs-keyword">End</span> <span class="hljs-keyword">If</span>
            <span class="hljs-keyword">Dim</span> builder <span class="hljs-keyword">As</span> <span class="hljs-built_in">New</span> StringBuilder

            <span class="hljs-comment">' Create a new PromptExecutionSettings object</span>
            <span class="hljs-keyword">Dim</span> executionSettings <span class="hljs-keyword">As</span> <span class="hljs-built_in">New</span> OpenAIPromptExecutionSettings()

            <span class="hljs-comment">' User question &#x26; answer loop</span>
            Chat.AddUserMessage(strSendMessage)

            builder.Clear()

            <span class="hljs-comment">' Get the AI response streamed back to the console</span>
            <span class="hljs-keyword">Dim</span> asyncEnumerator <span class="hljs-keyword">As</span> IAsyncEnumerator(<span class="hljs-keyword">Of</span> StreamingChatMessageContent) = Ai.GetStreamingChatMessageContentsAsync(Chat, executionSettings, kKernel).GetAsyncEnumerator()
            <span class="hljs-keyword">Try</span>
                <span class="hljs-keyword">While</span> <span class="hljs-built_in">Await</span> asyncEnumerator.MoveNextAsync()

                    <span class="hljs-keyword">Try</span>
                        <span class="hljs-keyword">Dim</span> message <span class="hljs-keyword">As</span> StreamingChatMessageContent = asyncEnumerator.Current
                        builder.Append(message.Content)

                    <span class="hljs-keyword">Catch</span> ex <span class="hljs-keyword">As</span> Exception

                    <span class="hljs-keyword">End</span> <span class="hljs-keyword">Try</span>
                <span class="hljs-keyword">End</span> <span class="hljs-keyword">While</span>

            <span class="hljs-keyword">Catch</span> ex <span class="hljs-keyword">As</span> Exception

            <span class="hljs-keyword">End</span> <span class="hljs-keyword">Try</span>

            Chat.AddAssistantMessage(builder.ToString())
            <span class="hljs-keyword">Return</span> builder.ToString()
        <span class="hljs-keyword">Catch</span> ex <span class="hljs-keyword">As</span> Exception

            <span class="hljs-keyword">Return</span> <span class="hljs-string">""</span>
        <span class="hljs-keyword">End</span> <span class="hljs-keyword">Try</span>
    <span class="hljs-keyword">End</span> <span class="hljs-keyword">Function</span>
</code></pre><p>然后调用时：</p><p>如果使用：</p><p>Return ModOllAmaAfterFirstChat(strFirstChat).result</p><p>在执行到函数的：</p><pre data-type="codeBlock" text="While Await asyncEnumerator.MoveNextAsync()
"><code><span class="hljs-keyword">While</span> <span class="hljs-built_in">Await</span> asyncEnumerator.MoveNextAsync()
</code></pre><p>语句时，就会死锁，始终得不到回应。</p><p>而使用：</p><p>Return Await ModOllAmaAfterFirstChat(strFirstChat)</p><p>就一切正常。</p><p>唯一的区别就是调用async函数的方式不同。</p><hr><p>然后大量查询资料，终于发现了秘密。</p><p>如以下例子：</p><pre data-type="codeBlock" text="static void Main(string[] args)
        {
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:start&quot;);

            Test(); //不等待
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:end&quot;);
            Console.Read();
        }

        static Task&lt;int&gt; Sleep()
        {
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Sleep start&quot;);
            Thread.Sleep(1000);
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Sleep end&quot;);
            return Task.FromResult(100);
        }
        
        static Task&lt;int&gt; Test()
        {
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Test start&quot;);
            var a=Task.Run(Sleep).Result;//由上一篇文章可知Run将会在线程池内调度执行
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Test end&quot;);
            return Task.FromResult(a);
        }
"><code>static void Main(<span class="hljs-keyword">string</span>[] args)
        {
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:start"</span>);

            Test(); <span class="hljs-comment">//不等待</span>
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:end"</span>);
            Console.Read();
        }

        static Task<span class="hljs-operator">&#x3C;</span><span class="hljs-keyword">int</span><span class="hljs-operator">></span> Sleep()
        {
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Sleep start"</span>);
            Thread.Sleep(<span class="hljs-number">1000</span>);
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Sleep end"</span>);
            <span class="hljs-keyword">return</span> Task.FromResult(<span class="hljs-number">100</span>);
        }
        
        static Task<span class="hljs-operator">&#x3C;</span><span class="hljs-keyword">int</span><span class="hljs-operator">></span> Test()
        {
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Test start"</span>);
            <span class="hljs-keyword">var</span> a<span class="hljs-operator">=</span>Task.Run(Sleep).Result;<span class="hljs-comment">//由上一篇文章可知Run将会在线程池内调度执行</span>
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Test end"</span>);
            <span class="hljs-keyword">return</span> Task.FromResult(a);
        }
</code></pre><p>运行结果：</p><p>1:start</p><p>1:Test start</p><p>4:Sleep start</p><p>4:Sleep end</p><p>1:Test end</p><p>1:end</p><p>由此可以看出Task.Result会阻塞主线程（Main函数），主线程必须等待被调用的子函数（最终被调用的子函数时是一个async函数：Sleep）执行完成后才能继续执行。</p><p>而如果是这样写：</p><pre data-type="codeBlock" text="static void Main(string[] args)
        {
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:start&quot;);

            TestAsync();//不等待

            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:end&quot;);
            Console.Read();
        }

        static Task&lt;int&gt; Sleep()
        {
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Sleep start&quot;);
            Thread.Sleep(1000);
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Sleep end&quot;);
            return Task.FromResult(100);
        }
        
        static async Task&lt;int&gt; TestAsync()
        {
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Test start&quot;);
            var a = await Task.Run(Sleep);
            Console.WriteLine($&quot;{Thread.CurrentThread.ManagedThreadId}:Test end&quot;);
            return a;
        }
"><code>static void Main(<span class="hljs-keyword">string</span>[] args)
        {
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:start"</span>);

            TestAsync();<span class="hljs-comment">//不等待</span>

            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:end"</span>);
            Console.Read();
        }

        static Task<span class="hljs-operator">&#x3C;</span><span class="hljs-keyword">int</span><span class="hljs-operator">></span> Sleep()
        {
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Sleep start"</span>);
            Thread.Sleep(<span class="hljs-number">1000</span>);
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Sleep end"</span>);
            <span class="hljs-keyword">return</span> Task.FromResult(<span class="hljs-number">100</span>);
        }
        
        static async Task<span class="hljs-operator">&#x3C;</span><span class="hljs-keyword">int</span><span class="hljs-operator">></span> TestAsync()
        {
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Test start"</span>);
            <span class="hljs-keyword">var</span> a <span class="hljs-operator">=</span> await Task.Run(Sleep);
            Console.WriteLine($<span class="hljs-string">"{Thread.CurrentThread.ManagedThreadId}:Test end"</span>);
            <span class="hljs-keyword">return</span> a;
        }
</code></pre><p>则运行结果是：</p><p>1:start</p><p>1:Test start</p><p>4:Sleep start</p><p>1:end</p><p>4:Sleep end</p><p>4:Test end</p><p>应当注意到，这儿没有等待Test函数执行完成，主函数main就执行完成了，同样主函数更没有等待Sleep函数执行完成就执行完成了。</p><hr><p>在看到这个例子之前，我看到的文章都说，一般情况下使用.result的写法多数会造成主线程阻塞，推荐使用await的写法，我还在想，是不是把之前的那些 函数调用写法都修改成await写法。</p><p>现在一看，其实是各有千秋，各有特色，我想这也是两种调用方法都存在的原因。</p><p>作此笔记的目的就是防止自己今后又记混。</p>]]></content:encoded>
            <author>nbrave51@newsletter.paragraph.com (Nbrave51)</author>
        </item>
    </channel>
</rss>