gpt4 book ai didi

c# - 在C#.NET4应用程序中在后台处理多个输入

转载 作者:太空狗 更新时间:2023-10-30 00:56:03 26 4
gpt4 key购买 nike

我正在寻找合适的模式和最佳的现代方法来解决以下问题:

我的应用程序期望来自多个来源的输入,例如:GUI,监视文件系统,语音命令,Web请求等。收到输入后,我需要将其发送到某种ProcessInput(InputData arg)方法,该方法将开始在后台处理数据,而不会阻止应用程序接收和处理更多数据,并且在处理完成时以某种方式返回一些结果。根据输入的不同,处理过程可能会花费截然不同的时间。对于初学者,我不需要检查进度或取消处理的能力。

在阅读了MSDN上的许多文章以及一些摇滚明星程序员的博客文章之后,我真的很困惑这里应该使用哪种模式,更重要的是.NET的哪些功能

我的发现是:

  • ThreadPool.QueueUserWorkItem-最容易理解,对于返回结果
  • 不太方便
  • BackgroundWorker-似乎仅用于相当简单的任务,所有工作程序都在单线程上运行?
  • Event-based Asynchronous Pattern
  • Tasks in Task Parallel Library
  • C# 5 async/await-这些似乎是Task Parallel
  • 中任务的快捷方式

    笔记:

    性能很重要,因此在可能的情况下利用多核系统将是非常不错的。

    这不是Web应用程序。

    我的问题让我想起了一个TCP服务器(实际上是任何类型的服务器),其中应用程序不断监听多个套接字上的新连接/数据,我发现了 Asynchronous Server Socket文章,我很好奇这种模式是否对我来说是可能的解决方案。

    最佳答案

    My application is expecting inputs from multiple sources, for example: GUI, monitoring file-system, voice command, web request, etc.



    我当时做过很多异步编程。我发现区分后台操作和异步事件很有用。您将启动“后台操作”,并在一段时间后完成。 “异步事件”是始终与程序无关的事件;您可以订阅,暂时接收事件,然后取消订阅。

    因此,GUI输入和文件系统监视将是异步事件的示例。而网络请求是后台操作。后台操作也可以分为CPU限制(例如,处理流水线中的某些输入)和I/O限制(例如,Web请求)。

    我特别在.NET中做出了这种区分,因为不同的方法有不同的优点和缺点。在进行评估时,您还需要考虑如何传播错误。

    首先,您已经找到的选项:
  • ThreadPool.QueueUserWorkItem-几乎是最糟糕的选择。它只能处理后台操作(没有事件),并且不能很好地处理受I/O约束的操作。返回结果和错误都是手动的。
  • BackgroundWorker(BGW)-不是最糟糕的,但绝对不是最好的。它还仅处理后台操作(无事件),并且不能很好地处理I/O绑定(bind)的操作。每个BGW都在自己的线程中运行-这很糟糕,因为您无法利用线程池的窃取工作的自平衡特性。此外,完成通知(通常)都排队在单个线程中,这可能会在非常繁忙的系统中造成瓶颈。
  • 基于事件的异步模式(EAP)-这是列表中的第一个支持异步事件以及后台操作的选项,它还可以有效地处理I/O绑定(bind)的操作。但是,正确编程有些困难,并且它与BGW(通常)都将完成通知都排队到单个线程中的问题相同。 (请注意,BGW是应用于CPU绑定(bind)的后台操作的EAP)。我写了a library来帮助编写EAP组件以及一些基于EAP的套接字。但是我不推荐这种方法。这些天有更好的选择。
  • 任务并行库中的
  • Tasks-Task是进行CPU绑定(bind)和I/O绑定(bind)的后台操作的最佳选择。 I review several background operation options on my blog-但是该博客文章根本没有解决异步事件。
  • C#5 async/await-这些允许更自然地表达基于Task的后台操作。如果需要,它们还提供了一种简便的方法来同步回到调用者的上下文(对UI发起的操作很有用)。

  • 在这些选项中, async/ await是最容易使用的, Task紧随其后。这些问题是它们是为后台操作而不是异步事件而设计的。

    只要您有足够的缓冲区来处理这些事件,就可以使用异步操作(例如 Task)来消耗任何异步事件源。当您有一个缓冲区时,您可以在每次异步操作完成时重新启动它。某些缓冲区是由操作系统提供的(例如,套接字具有读取缓冲区,UI窗口具有消息队列等),但是您可能必须自己提供其他缓冲区。

    话虽如此,这是我的建议:
  • Task-based Asynchronous Pattern (TAP)-直接使用await/asyncTask,使用TAP至少对您的后台操作建模。
  • TPL Dataflow(VS Async的一部分)-允许您设置“管道”以供数据通过。数据流基于Task。 Dataflow的缺点是它仍在开发中(IMO)并不像其他异步支持那样稳定。
  • Reactive Extensions (Rx)-这是专门为异步事件设计的唯一选项,而不仅仅是后台操作。它已正式发布(与VS Async和Dataflow不同),但是学习曲线更加陡峭。

  • 所有这三个选项都很有效(使用线程池进行任何实际处理),并且它们都具有定义明确的语义,用于错误处理和结果。我建议尽可能使用TAP。这些部分然后可以轻松地集成到Dataflow或Rx中。

    您提到“语音命令”作为一种可能的输入源。您可能对Stephen Toub唱歌的 BuildWindows video感兴趣,并使用Dataflow几乎实时地协调他的声音。 (Stephen Toub是TPL,Dataflow和Async背后的天才之一)。

    关于c# - 在C#.NET4应用程序中在后台处理多个输入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8624135/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com