具有多线程/任务的C#/ .NET应用程序设计

时间:2015-04-21 14:18:02

标签: c# .net multithreading workflow state

我想设计一个应用程序,在两个完全独立的系统之间提供双向通信。(网桥)
其中一个可以通过Web服务调用我的应用程序 - 另一个是第三方硬件。它说RS232。使用RS232< - > ETH收发器,我们设法使用TCP与硬件通信。

该计划具有以下要求

  • 有一个运行“管理服务”的主线程。例如,这可能是WCF端点或自托管的webapi REST服务。它提供了启动新工作器实例或获取所有工作器实例及其各自状态的列表的方法。
  • 有许多“工人”线程。他们每个人都有一个有5个州的州模型。
  • 例如,在一种状态下,必须生成TCP侦听器以接受来自连接的硬件设备的传入连接(基于套接字的编程是必需的)。一旦获得所需信息,它就会发回响应并转换到下一个状态。
  • 应该可以从main(manager)线程到(正常)结束单个工作线程(例如,如果工作线程卡在无法恢复的状态)

这是我来自的地方:

  • 我考虑过WCF工作流服务(状态模型活动)但是我不确定如何在那里生成TcpListener并保持活着。我不需要任何工作流程“暂停/序列化和恢复/反序列化”行为。
  • 主线程可能不是那么令人担忧 - 只需要在那里运行。这是孩子(背景)线程及其内部状态机让我担心。
  • 我试图围绕任务可能在这里提供帮助,但我最终认为线程实际上更适合任务

由于.NET中有很多开发(4+)我不确定采用哪种方法 ...互联网上充满了2005年至2010年的例子,这些例子可能超过刚过时了将DO与DONT分开是非常困难的。

我很高兴有任何提示。

更新:好的,我会尝试澄清我的问题是什么......

我认为最简单的方法是提供一些伪代码。

public static void Main()
{
    // Start self-hosted WCF service (due to backwards compatibility, otherwise I'd go with katana/owin) on a worker thread
    StartManagementHeadAsBackgroundThread();

    // Stay alive forever
    while(running)
    {
        // not sure what to put here. Maybe Thread.Sleep(500)?
    }

    // Ok, application is shutting down => somehow "running" is not true anymore.
    // One possible reason might be: The management service's "Shutdown()" method is being called
    // Or the windows service is being stopped...

    WaitForAllChildrenToReachFinalState();
}

private static void StartManagementHeadAsBackgroundThread()
{
     ThreadStarter ts = new ThreadStarter(...);
     Thread t = new Thread(ts);
     t.Start();
}

管理主管(= wcf服务)提供了一些方法

  • StartCommunicator()启动新的工作线程,以5个状态执行实际工作
  • Shutdown()关闭整个应用程序,让所有工作线程优雅地完成(通常是几分钟的问题)
  • GetAllCommunicatorInstances()显示所有工作线程的摘要及其所处的当前状态。
  • DestroyCommunicatorInstance(port)强制结束工作线程 - 例如,如果通信器卡在无法恢复的状态。

无论如何,我需要从“管理”服务(StartCommunicator方法)中生成新的后台线程。

public class Communicator
{
    private MyStateEnum _state;
    public Communicator(int port)
    {
       _state = MyStateEnum.Initializing;
       // do something
       _state = MyStateEnum.Ready;
    }

    public void Run()
    {
        while(true)
        {
             // again a while(true) loop?!
             switch(_state):
             {
                 case MyStateEnum.Ready:
                 {
                     // start TcpListener - wait for TCP packets to arrive.
                     // parse packets. If "OK" set next good state. Otherwise set error state.
                 }
             }

             if(_state == MyStateEnum.Error) Stop();
             break;
        }
    }

    public void Stop()
    {
        // some cleanup.. disposes maybe. Not sure yet.
    }
}

public enum MyStateEnum
{
     Initializing, Ready, WaitForDataFromDevice, SendingDataElsewhere, Done, Error
}

所以问题是我的方法是否会带我到任何地方,或者我是否完全走错了路。
我该如何实现这一目标?主题?任务?是(真)有效吗?如何从“管理服务”中与通信器实例进行交互?我正在寻找的是带注释的锅炉板解决方案:)

2 个答案:

答案 0 :(得分:0)

我的建议是使用ASP.NET Web API服务并将Controller操作标记为异步。从那时起,尽可能使用Tasks,当您最终阻止IO时,不会阻止HTTP服务器。就个人而言,我会避免使用Threads,直到你完全确定你不能用Tasks完成同样的事情。

答案 1 :(得分:0)

我建议使用线程池。这将有助于管理资源并提高资源的使用效率。

就终止线程而言,线程池线程是后台工作线程,并且当您的服务停止时将终止,但是,从上面的描述中这是不够的。您的线程应始终能够接收要求终止的消息。

相关问题