加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > Windows > 正文

wcf – 我们可以将Workflow服务作为Windows服务托管吗?

发布时间:2020-12-14 04:27:33 所属栏目:Windows 来源:网络整理
导读:我正在开发一个日志应用程序,它要求我有一个作为服务公开的工作流程(工作流程服务).我们希望将其作为 Windows服务托管(不希望将工作流服务作为IIS中的.svc文件托管).将其作为Windows服务的另一个原因是能够通过命名管道与服务进行通信. 我们是否可以通过命名
我正在开发一个日志应用程序,它要求我有一个作为服务公开的工作流程(工作流程服务).我们希望将其作为 Windows服务托管(不希望将工作流服务作为IIS中的.svc文件托管).将其作为Windows服务的另一个原因是能够通过命名管道与服务进行通信.

我们是否可以通过命名管道公开工作流服务而无需在IIS中托管它?

解决方法

是的,你确定可以.至少,我已经完成了Workflow 4 Release Candidate.

考虑,

// a generic self-hosted workflow service hosting thingy. Actual
// implementation should contain more logging and thread safety,this
// is an abbreviated version ;)
public class WorkflowHost
{

    // NOTE: with Workflow,it helps to maintain a concept of
    // Workflow definition [the Activity or WorkflowService from
    // a designer] and a Workflow instance [what is running within
    // WorkflowInvoker,WorkflowApplication,WorkflowServiceHost].
    // a definition may be used to generate an instance. an instance
    // contains run-time state and cannot be recycled into a new
    // instance. therefore,to repeatedly re-host a WorkflowService
    // we need to maintain references to original definitions and
    // actual instances. ergo services and hosts maps
    // 
    // if you are special purpose and require support for one and 
    // only one service and endpointuri,then you may reduce this 
    // to a simple tuple of Uri,WorkflowService,WorkflowServiceHost

    // services represents a definition of hosted services
    private readonly Dictionary<Uri,WorkflowService> _services = 
        new Dictionary<Uri,WorkflowService> ();

    // hosts represents actual running instances of services
    private readonly Dictionary<Uri,WorkflowServiceHost> _hosts = 
        new Dictionary<Uri,WorkflowServiceHost> ();

    // constructor accepts a map of Uris (ie service endpoints) to
    // workflow service definitions
    public WorkflowHost (IDictionary<Uri,WorkflowService> services)
    {
        foreach (KeyValuePair<Uri,WorkflowService> servicePair in services)
        {
            _services.Add (servicePair.Key,servicePair.Value);
        }
    }

    // have your windows service invoke this to start hosting
    public void Start ()
    {
        if (_hosts.Count > 0)
        {
            Stop ();
        }

        foreach (KeyValuePair<Uri,WorkflowService> servicePair in _services)
        {
            WorkflowService service = servicePair.Value;
            Uri uri = servicePair.Key;
            WorkflowServiceHost host = new WorkflowServiceHost (service,uri);

            host.Open ();

            _hosts.Add (uri,host);
        }
    }

    // have your windows service invoke this to stop hosting
    public void Stop ()
    {
        if (_hosts.Count > 0)
        {
            foreach (KeyValuePair<Uri,WorkflowService> servicePair in 
                _services)
            {
                WorkflowService service = servicePair.Value;
                Uri uri = servicePair.Key;

                IDisposable host = _hosts[uri];
                host.Dispose ();
            }

            _hosts.Clear ();
        }
    }
}

我相信可以通过App.config中的标准Wcf服务配置部分设置端点配置.在我的Workflow实验中,我没有亲自尝试更改默认传输层.

以上代表了一个通用的纯托管类[即它自托管WorkflowServices].这允许我们在控制台,WinForm,WPF或是,甚至是WindowsService应用程序中重用此托管功能.下面是一个利用我们的宿主类的WindowsService

// windows service. personally i would abstract service behind
// an interface and inject it,but again,for brevity ;)
public partial class WorkflowWindowsService : ServiceBase
{
    WorkflowHost _host;

    public WorkflowWindowsService ()
    {
        InitializeComponent();

        Dictionary<Uri,WorkflowService> services = 
            new Dictionary<Uri,WorkflowService> ();

        // do your service loading ...

        // create host
        _host = new WorkflowHost (services);
    }

    protected override void OnStart(string[] args)
    {
        _host.Start ();
    }

    protected override void OnStop()
    {
        _host.Stop ();
    }
}

如果您在VS2010RC中摆弄了WorkflowServices,那么您可能已经知道WorkflowServices不是像他们的Workflow表兄弟那样的一流Xaml类.相反,它们被保存为带有.xamlx扩展名的松散Xaml文件. WorkflowServices没有设计时智能感知支持[据我所知]并且不被识别为声明类型,因此我们在运行时加载WorkflowService的唯一选择是

>直接从.xamlx文件中读取纯Xaml标记
>从其他来源[嵌入字符串,资源或其他来源]读取纯Xaml标记

无论哪种方式,我们必须解释标记并创建WorkflowService定义.以下内容将字符串[可能是文件名或标记]转换为WorkflowService. Keeners还可能注意到此流程与将工作流标记转换为工作流定义的过程之间存在差异.

// converts a string value [either pure xaml or filename] to a
// WorkflowService definition
public WorkflowService ToWorkflowService (string value)
{
    WorkflowService service = null;

    // 1. assume value is Xaml
    string xaml = value;

    // 2. if value is file path,if (File.Exists (value))
    {
        // 2a. read contents to xaml
        xaml = File.ReadAllText (value);
    }

    // 3. build service
    using (StringReader xamlReader = new StringReader (xaml))
    {
        object untypedService = null;

        // NOTE: XamlServices,NOT ActivityXamlServices
        untypedService = XamlServices.Load (xamlReader);

        if (untypedService is WorkflowService)
        {
            service = (WorkflowService)(untypedService);
        }
        else
        {
            throw new ArgumentException (
                string.Format (
                "Unexpected error reading WorkflowService from " + 
                "value [{0}] and Xaml [{1}]. Xaml does not define a " + 
                "WorkflowService,but an instance of [{2}].",value,xaml,untypedService.GetType ()));
        }
    }

    return service;
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读