WCF开发框架形成之旅--WCF应用常见问题处理

本文继续前面几篇关于WCF开发框架的随笔,继续介绍WCF的一些经验和知识,其中主要介绍在使用WCF开发中碰到的问题以及解决方法,为自己做个记号,也为后来者提供解决思路,其中包括有动态修改 WCF配置内容、规范WCF客户端的调用和处理。 

1、 动态修改WCF配置内容

由于在软件登录界面中,需要提供用户切换内网、外网的功能,而配置文件中内外网的地址配置是不一样的,因此需要动态修改应用程序的配置文件,然后更新其中节点内容,界面如下所示。

 

修改WCF节点的C#代码如下所示

        private void ChangeConfig() 

        {
            bool isIntranet = radNetType.EditValue.ToString() == "内网";
            if (isIntranet)
            {
                UpdateConfig("192.168.1.2", "8002");
            }
            else
            {
                UpdateConfig("219.136.1.2", "8002");
            }
        }

        private void UpdateConfig(string serverIPAddress, string serverPort)
        {
            //Configuration config = ConfigurationManager.OpenExeConfiguration(Assembly.GetEntryAssembly().Location);  
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            ConfigurationSectionGroup sct = config.SectionGroups["system.serviceModel"];
            ServiceModelSectionGroup serviceModelSectionGroup = sct as ServiceModelSectionGroup;
            ClientSection clientSection = serviceModelSectionGroup.Client;

            foreach (ChannelEndpointElement item in clientSection.Endpoints)
            {
                string pattern = "://.*/";
                string address = item.Address.ToString();
                if (address.ToLower().Contains("localhost"))
                    return;

                string replacement = string.Format("://{0}:{1}/", serverIPAddress, serverPort);
                address = Regex.Replace(address, pattern, replacement);
                item.Address = new Uri(address);
            }

            config.Save(ConfigurationSaveMode.Modified);
            ConfigurationManager.RefreshSection("system.serviceModel");
        }

其中为了调试方便,在修改配置文件代码里面,判断地址如果是localhost的则不进行修改切换。

2、 规范WCF客户端的调用处理。

在创建WCF服务客户端实例的时候,我们可能会这样共创建客户端并调用,就是在窗体的顶部,创建一个该窗体内的全局WCF服务客户端实例。

    public partial class FrmParkUser : BaseDock
    {
        private DeviceUserServiceClient client = new DeviceUserServiceClient();
        public string ID = string.Empty;

        public FrmParkUser()
        {
            InitializeComponent();
        }

        .................  

实际使用wcf客户端的时候,我们可能会这样调用。

            this.winGridViewPager1.PagerInfo.RecordCount = client.GetRecordCount2(where);

            this.winGridViewPager1.DataSource = client.SearchParkUser(where, this.winGridViewPager1.PagerInfo);

OK,其实这样使用看起来是没什么问题的,而且也能顺利使用,不过,由于wcf客户端都有一个超时时间,可能静止过了一段时间,你在界面刷新数据的时候,你会发现出现下面的错误:"通信对象 System.ServiceModel.Channels.ServiceChannel 无法用于通信,因为其处于“出错”状态。" 

或者是一些奇怪的错误信息。

既然上面的调用不好,那么我们应该如何调用客户端呢,有人这样调用。

using (var client = new SomeWCFServiceClient()) 
{
    //Do something with the client 

}  

其实这样操作,更不好,也会出现上面红色的错误,微软建议的调用方式应该是这样的

try
{
    ...
    client.Close();
}
catch (CommunicationException e)
{
    ...
    client.Abort();
}
catch (TimeoutException e)
{
    ...
    client.Abort();
}
catch (Exception e)
{
    ...
    client.Abort();
    throw;

}  

但如果调用频繁,这样实在不雅,管理也非常难受。有没有更好的方式,避免出错,又能够正确调用wcf客户吗,当然有,下面这样方式就是比较好的一种解决方案,经过实际测试,效果不错。

1、 首先创建一个扩展辅助类,代码如下所示

    /// <summary>
    /// WCF服务包装类,避免使用Using等方式导致服务出错的问题
    /// </summary>
    public static class WcfExtensions
    {
        public static void Using<T>(this T client, Action<T> work)
            where T : ICommunicationObject
        {
            try
            {
                work(client);
                client.Close();
            }
            catch (CommunicationException e)
            {
                client.Abort();
            }
            catch (TimeoutException e)
            {
                client.Abort();
            }
            catch (Exception e)
            {
                client.Abort();
                throw;
            }
        }

    }   

然后实际调用的时候,如下即可,看起来还是非常简单的,这样是即需创建的代理客户端,即使很久不操作,也不会发生超时等错误信息了。

        private void GetTable()
        {
            new EnterpriseServiceClient().Using(enterpriseClient =>
            {
                DataTable dt = enterpriseClient.GetAllForLookUp();
                this.searchPark.Properties.DisplayMember = "PARK_NAME";
                this.searchPark.Properties.ValueMember = "ID";
                this.searchPark.Properties.DataSource = dt;
            }); 

            new ManufacturerServiceClient().Using(manufacturerClient =>
            {
                ManufacturerInfo[] manuList = manufacturerClient.GetAll();
                this.searchCompany.Properties.DisplayMember = "CompanyName";
                this.searchCompany.Properties.ValueMember = "ID";
                this.searchCompany.Properties.DataSource = manuList;
            }); 
       } 

 或者如下例子。

            ManufacturerInfo info = null;
            new ManufacturerServiceClient().Using(manufacturerClient =>
                {
                    info = manufacturerClient.FindByID(searchCompany.EditValue.ToString());
                });
            if (info != null)
            {
                this.txtCompanyAddr.Text = info.CompanyAddr;
            } 

 本文转自博客园伍华聪的博客,原文链接:WCF开发框架形成之旅--WCF应用常见问题处理,如需转载请自行联系原博主。

时间: 2024-07-31 13:19:30

WCF开发框架形成之旅--WCF应用常见问题处理的相关文章

WCF开发框架形成之旅---终极WCF框架是什么样子的

前面几篇WCF框架的文章,一直是介绍我的WCF框架的形成中的知识,期间虽然我在工作项目中已经成功运用各种WCF的概念及特性,而且是多个部门之间的数据管理系统,基本上WCF框架的雏形已经形成了,不过我一直想把我成熟的Winform开发框架,提炼整合到WCF框架上,这样在成熟的Winform框架基础上应用的WCF技术,才是我整个WCF开发框架的终极形式,虽然项目时间很紧,但业余空闲时间我一直未曾停步,前阵子通宵达旦完成,并经过多番测试,今天有幸和大家分享一下这个WCF框架的真面目及其中的一些经验总结

WCF开发框架形成之旅---结合代码生成工具实现快速开发

我的WCF开发框架推出很久了,一直有不少的朋友支持及提供良好的完善意见,随着利用这种基于Winform界面的WCF开发框架开发了不同类型的项目,各种WCF对象的调用及处理逐渐稳定及统一化,因此是时候让我的开发伴侣(代码生成工具Database2Sharp)来做更多更有技术性的工作了---提供基于我的WCF开发框架模式创建的项目工程及调用WCF的Winform界面处理代码.这样在WCF快速开发框架中,有了更强更高效率的支持,整个项目的开发,就更加是水到渠成,闲庭散步了. 因此,代码生成工具生成框架

WCF开发框架形成之旅--个人图片信息的上传保存

一般在业务系统里面,除了存储个人的基本信息外,可能也都需要存储个人的一些图片信息,通常如肖像.名片.身份证等重要图片信息,而这些信息偏小为了方便管理,一般也是和个人基本信息一起放在数据库里面的. 本人在开发形成自己的Winform开发框架及WCF开发框架过程中,对这些进行了优化整理,现公布出来和大家一起讨论学习,希望给大家提供一个参考外,自己有进一步的提升.本文主要以WCF开发框架下的个人图片信息上传保存作为主题,介绍其中涉及到的一些知识点和操作,以及规避其中一些常见的问题. 1)首先,我们需要

WCF开发框架形成之旅--您的数据是否需要加密

基于WCF技术,搭建基于分布式的网络应用,目前已经是很常见的应用,在上篇随笔<基于我的Winform开发框架扩展而成的WCF开发框架>中,介绍了我自己的Winform开发框架的一些基础知识及扩展而成的WCF开发框架,上篇随笔只是基于快速应用搭建而成的WCF框架,并没有考虑到数据安全性的问题,在互联网的环境中,数据的安全性是必须考虑的一道门槛,否则明文数据满天飞,犹如人在大街上裸奔一样令人不安,除非是你认为你的应用数据无关紧要.本文主要通过技术对比,介绍如何创建一个Winform客户端测试WCF

WCF开发框架之插件化应用模式升级

自从在<Winform开发框架之插件化应用框架实现>一文中,介绍并总结了Winform开发框架插件化应用框架的实现后,赢得了很多同行和客户的支持,于是把我的WCF开发框架.混合式开发框架都进行了升级,把它们都提升到插件化应用的高度上.本文主要介绍WCF开发框架,如何实现插件化的应用.从我随笔<基于我的Winform开发框架扩展而成的WCF开发框架>介绍可以看到,一般的WCF应用,是在客户端添加服务应用的方式,然后使用自动生成的WCF服务客户端代理来访问相应的服务的,这种方式比较方便

WCF开发框架的案例应用总结

在我的<Winform开发框架>系列文章中,除了介绍Winform开发框架外,还详细介绍了基于Winform开发框架的WCF开发框架,WCF开发框架除了具有Winform程序的丰富体验,绚丽的界面外,还具备Web应用程序的分布式应用特点,数据库服务端配置而不用客户端操心等特点,而随着.NET4.0的出现,只有40多M的安装包,也确实为WCF应用的推广使用更加方便.由于WCF应用的分布式这个重要的特点,客户数据全部保存在服务端,因此也提高了数据的安全性,因此很多传统应用的场合都可以使用WCF技术

我的WCF开发框架简化版及基于NET.TCP传输方式的实现

前面介绍很多关于我的WCF开发框架的文章,前面的介绍思路,主要是基于一个整个仓库管理系统来进行整体介绍的,本来另辟蹊径,着重介绍一个备件信息的表的在我的WCF开发框架中,各层是如何体现的,通过简单的一个表的操作,走完一个WCF开发过程,着重介绍一个对象类,如何实现整个wcf的应用.另外穿插介绍如何基于net.tcp传输方式实现wcf的应用,以及使用这种方式需要注重的地方等功能模块的介绍. 我们先来看看我的WCF开发框架整体架构设计图.   上图中,值得注意的是,WCF服务层,可以Host(寄宿)

Winform开发之离线式WCF开发框架的实现介绍

在上篇随笔<Winform开发框架之框架演化>中介绍了几种Winform开发框架,其中有对于离线式WCF开发框架的介绍,离线式的WCF开发框架 ,就是结合了传统Winform开发框架的数据访问方式,又利用了WCF分布式数据获取的特点,使得数据可以离线使用,在一种业务要求集中化,又要求不影响正常业务操作的应用系统场景下比较适合.本文主要介绍如何利用我的Winform开发框架的整体思路,实现WCF开发框架的离线式的数据上传.更新的同步操作. 其实目前企业集中化管理,这种模式要求很多,如一些加盟店的

基于我的Winform开发框架扩展而成的WCF开发框架

一直以来,多数时间在开发一些Winform共享软件,经过多年的积累,逐渐形成比较成熟稳定的Winform开发框架,并结合Web项目开发经验.代码生成工具.相关的控件开发及项目开发经验,逐渐形成一个相对比较完善的.NET开发体系.不过由于种种原因,甚少涉足WCF的相关应用,只是在09年初的时候,开发一个送水软件网络版的时候,玩过WCF,那时候主要是把WCF作为一个送水各种业务数据的同步服务实现.由于研究兴趣及工作便利等原因,最近学习研究,把WCF服务搭建在我传统的Winform开发框架基础上,完成