【发布时间】:2019-12-10 20:09:56
【问题描述】:
我是使用 TPL 的新手。我已经能够在 BufferBlock 上实现一个简单的发布/接收事务,但是当我尝试异步时,我被挂了。
这是我正在尝试的简化版本。
声明消息缓冲区(使其成为全局)
Dim msgBuffer As New BufferBlock(Of String)
一个简单的发布消息的函数,它只是一个目录中的文件名列表
Private Sub PostMessagesToBuffer()
filesList = Directory.GetFiles(txtBoxSrcFilesDir.Text, fileFilter).ToList
For Each file In filesList
msgBuffer.Post(file)
Next
msgBuffer.Complete()
End Sub
我创建了这个函数来处理消息:
Private Async Function ProcessMessagesAsync() As Task(Of Integer)
Dim msgsProcessed = 0
While Await msgBuffer.OutputAvailableAsync
Dim msg = msgBuffer.Receive
Console.WriteLine(msg)
msgsProcessed += 1
End While
Return msgsProcessed
End Function
然后只需这组调用即可全部运行。
Dim msgProcessor = ProcessMessagesAsync()
PostMessagesToBuffer()
msgProcessor.Wait()
Console.writeLine("Processed " & msgProcessor.Result & " Messages.")
我可以调试并看到消息被添加到缓冲区中,但“等待时”从未收到消息在队列中可用的信号。它只是坐在那里,永远不会进入循环来处理消息。我在这里错过了一些相当简单的东西吗?
【问题讨论】:
-
这是一个明显的死锁情况,代码无法通过 While 循环到达 PostMessagesToBuffer()。这通常发生在另一个线程上。
-
这是什么应用程序?控制台应用程序? Windows 窗体?
-
这是一个 Windows 窗体应用程序。
-
这是有道理的。您的代码不应在控制台应用程序中死锁。但是 Windows 窗体应用程序在 UI 线程中安装了一个同步上下文,以强制异步工作流在
await之后在 UI 线程中继续,这非常有用,但如果 UI 线程由于某种原因被阻塞,则会引入死锁的可能性.
标签: vb.net asynchronous async-await task-parallel-library tpl-dataflow