CommunicationObjectFaultedException - System.ServiceModel.Channels.ServiceChannel不能用于通信,因为它处于故障状态

时间:2016-01-27 19:18:53

标签: c# asynchronous exception-handling communicationexception

我正在使用C#进行EConnect集成。我正在研究一个测试GP连接字符串的函数。基本上,字符串由GP的数据服务器名称和数据库名称组成。如果数据库名称错误,则抛出eConnect异常,并且很容易捕获并跟踪。当服务器名称错误时,用于测试连接的getentity函数将只是旋转和超时。所以我使用IAsyncResult和等待句柄来测试应用程序是否超时。如果应用程序超时,我重新启动服务并允许用户重新输入服务器名称。现在我遇到的问题是在我测试输入错误的服务器并且一切都被重置后我得到了System.ServiceModel.CommunicationObjectFaultedException。

以下是我从异常中获得的信息:

An exception of type 'System.ServiceModel.CommunicationObjectFaultedException' occurred in System.ServiceModel.dll but was not handled in user code

Additional information: The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.

System.ServiceModel.CommunicationObjectFaultedException was unhandled by user code
  HResult=-2146233087
  Message=The communication object, System.ServiceModel.Channels.ServiceChannel, cannot be used for communication because it is in the Faulted state.
  Source=System.ServiceModel
  StackTrace:
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelFactory.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelFactory.TypedServiceChannelFactory`1.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at System.ServiceModel.ChannelFactory.OnClose(TimeSpan timeout)
   at System.ServiceModel.Channels.CommunicationObject.Close(TimeSpan timeout)
   at Microsoft.Dynamics.GP.eConnect.ServiceProxy.Dispose()
   at Microsoft.Dynamics.GP.eConnect.eConnectMethods.Dispose()
   at GP_Import___Sylectus.UpdateGPConnection.TestGPConnection() in C:\GP Import - Sylectus\GP Import - Sylectus\UpdateGPConnection.cs:line 265
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.AsyncProcessMessage(IMessage msg, IMessageSink replySink)
  InnerException: 

这是我的代码:

namespace GP_Import___Sylectus
{
    public partial class UpdateGPConnection : Form
    {
        Task task;
        AsyncCallback cb;
        public delegate string startProcessToCall();
        startProcessToCall sp2c;
        bool test = false;
        string testResult = "";            

        public UpdateGPConnection()
        {
            InitializeComponent();
            this.txtDatasourceName.Text = ConfigurationManager.AppSettings.Get("GPDataServer");
            this.txtDatabaseName.Text = ConfigurationManager.AppSettings.Get("GPDatabase");                        

            cb = new AsyncCallback(startProcessCallback);
            sp2c = new startProcessToCall(TestGPConnection);
        }

        public void startProcessCallback(IAsyncResult iar)
        {
            startProcessToCall mc = (startProcessToCall)iar.AsyncState;
            //bool result = mc.EndInvoke(iar);
            //Console.WriteLine("Function value = {0}", result);
        }

        private void btnUpdate_Click(object sender, EventArgs e)
        {
            var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            config.AppSettings.Settings["GPDataServer"].Value = txtDatasourceName.Text.ToUpper();
            config.AppSettings.Settings["GPDatabase"].Value = txtDatabaseName.Text.ToUpper();
            config.Save(ConfigurationSaveMode.Modified);

            ConfigurationManager.RefreshSection("appSettings");

            GPCongfigSettings.GPConnectionString = @"data source=" + txtDatasourceName.Text.ToUpper() + ";initial catalog=" + txtDatabaseName.Text.ToUpper() + ";integrated security=SSPI;persist security info=False;packet size=4096";

            IAsyncResult asyncResult = null;
            asyncResult = sp2c.BeginInvoke(cb, null);


            Thread.Sleep(0);

            Cursor.Current = Cursors.WaitCursor;
            test = asyncResult.AsyncWaitHandle.WaitOne(15000);

            if (test)
            {
                try
                {
                    testResult = sp2c.EndInvoke(asyncResult);
                }
                catch (Exception exc)
                {
                    Console.WriteLine(exc.Message);
                }
            }

            bool result = asyncResult.IsCompleted;

            string eConnectServiceName = ConfigurationManager.AppSettings.Get("eConnectServiceName");

            string eConnectProcess = ConfigurationManager.AppSettings.Get("eConnectProcess");

            Process[] process = Process.GetProcessesByName(eConnectProcess);

            if (!test)
            {                          

                foreach (Process tempProcess in process)
                {
                    tempProcess.Kill();
                }
                RestartService(eConnectServiceName, 20000);

                RestartService(eConnectServiceName, 20000);
            }

            asyncResult.AsyncWaitHandle.Close();


            Cursor.Current = Cursors.Default;                

            if (test == false)
            {
                MessageBox.Show("Dataserver Name is Incorrect", "Connection String Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
            }
            else
            {
                if (testResult == "Correct Connection")
                {
                    MessageBox.Show("Connection String Successfully Updated", "", MessageBoxButtons.OK);
                    this.Close();
                }
                else if (testResult.Contains("eConnect Exception"))
                {
                    MessageBox.Show("Database Name is Incorrect", "Connection String Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                }
                else
                {
                    MessageBox.Show(testResult, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    RestartService(eConnectServiceName, 20000);
                }
            }            
        }          

        public string TestGPConnection()
        {

            eConnectMethods requester = new eConnectMethods();
            try
            {                

                // Create an eConnect document type object
                eConnectType myEConnectType = new eConnectType();

                // Create a RQeConnectOutType schema object
                RQeConnectOutType myReqType = new RQeConnectOutType();

                // Create an eConnectOut XML node object
                eConnectOut myeConnectOut = new eConnectOut();

                // Populate the eConnectOut XML node elements
                myeConnectOut.ACTION = 1;
                myeConnectOut.DOCTYPE = "GL_Accounts";
                myeConnectOut.OUTPUTTYPE = 2;
                myeConnectOut.FORLIST = 1;
                myeConnectOut.WhereClause = "(ACTNUMST = '99-9999-99-999')";

                // Add the eConnectOut XML node object to the RQeConnectOutType schema object
                myReqType.eConnectOut = myeConnectOut;

                // Add the RQeConnectOutType schema object to the eConnect document object
                RQeConnectOutType[] myReqOutType = { myReqType };
                myEConnectType.RQeConnectOutType = myReqOutType;

                // Serialize the eConnect document object to a memory stream
                MemoryStream myMemStream = new MemoryStream();
                XmlSerializer mySerializer = new XmlSerializer(myEConnectType.GetType());
                mySerializer.Serialize(myMemStream, myEConnectType);
                myMemStream.Position = 0;

                // Load the serialized eConnect document object into an XML document object
                XmlTextReader xmlreader = new XmlTextReader(myMemStream);
                XmlDocument myXmlDocument = new XmlDocument();
                myXmlDocument.Load(xmlreader);

                var tokenSource = new CancellationTokenSource();
                CancellationToken token = tokenSource.Token;
                int timeOut = 20000; //20 seconds

                try
                {
                    string reqDoc = requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml);
                }
                catch (CommunicationObjectFaultedException cofe)
                {
                    return "Communication Exception - " + cofe.Message;
                }

                //connection string is correct
                return "Correct Connection";


            }
            catch (FaultException fe)
            {
                return "Fault Exception - " + fe.Message;
            }
            catch (eConnectException exc)
            {
                Console.WriteLine(exc.Message);
                return "eConnect Exception - " + exc.Message;
            }            
            catch (CommunicationObjectFaultedException cofe)
            {
                return "Communication Exception - " + cofe.Message;
            }
            catch (Exception ex)
            {
                return "Exception - " + ex.Message;
            }
            finally
            {
                // Release the resources of the eConnectMethods object
                requester.Dispose();
            }
        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        public static void RestartService(string serviceName, int timeoutMilliseconds)
        {
            ServiceController service = new ServiceController(serviceName);
            try
            {

                int millisec1 = Environment.TickCount;
                TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);

                if (!service.Status.Equals(ServiceControllerStatus.Stopped))
                {
                    service.Stop();
                    service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
                }


                // count the rest of the timeout
                int millisec2 = Environment.TickCount;
                timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds - (millisec2 - millisec1));

                if (service.Status.Equals(ServiceControllerStatus.Stopped) || service.Status.Equals(ServiceControllerStatus.StopPending))
                {
                    service.Start();
                    service.WaitForStatus(ServiceControllerStatus.Running, timeout);
                }
            }
            catch (Exception ex)
            {
                // ...
            }
        }          


    }

}

当我尝试在TestGPConnection中处理请求方法时,似乎总是会出现错误。

我应该做些什么?我一直在谷歌搜索这一天,我很困惑我发现如何解决这个问题。

1 个答案:

答案 0 :(得分:0)

尝试更改代码:


        public string TestGPConnection()
        {
            try
            {                
               using (eConnectMethods requester = new eConnectMethods())
               {
                // Create an eConnect document type object
                eConnectType myEConnectType = new eConnectType();

                // Create a RQeConnectOutType schema object
                RQeConnectOutType myReqType = new RQeConnectOutType();

                // Create an eConnectOut XML node object
                eConnectOut myeConnectOut = new eConnectOut();

                // Populate the eConnectOut XML node elements
                myeConnectOut.ACTION = 1;
                myeConnectOut.DOCTYPE = "GL_Accounts";
                myeConnectOut.OUTPUTTYPE = 2;
                myeConnectOut.FORLIST = 1;
                myeConnectOut.WhereClause = "(ACTNUMST = '99-9999-99-999')";

                // Add the eConnectOut XML node object to the RQeConnectOutType schema object
                myReqType.eConnectOut = myeConnectOut;

                // Add the RQeConnectOutType schema object to the eConnect document object
                RQeConnectOutType[] myReqOutType = { myReqType };
                myEConnectType.RQeConnectOutType = myReqOutType;

                // Serialize the eConnect document object to a memory stream
                MemoryStream myMemStream = new MemoryStream();
                XmlSerializer mySerializer = new XmlSerializer(myEConnectType.GetType());
                mySerializer.Serialize(myMemStream, myEConnectType);
                myMemStream.Position = 0;

                // Load the serialized eConnect document object into an XML document object
                XmlTextReader xmlreader = new XmlTextReader(myMemStream);
                XmlDocument myXmlDocument = new XmlDocument();
                myXmlDocument.Load(xmlreader);

                var tokenSource = new CancellationTokenSource();
                CancellationToken token = tokenSource.Token;
                int timeOut = 20000; //20 seconds

                try
                {
                    string reqDoc = requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml);
                }
                catch (CommunicationObjectFaultedException cofe)
                {
                    return "Communication Exception - " + cofe.Message;
                }

                //connection string is correct
                return "Correct Connection";
                }
            }
            catch (FaultException fe)
            {
                return "Fault Exception - " + fe.Message;
            }
            catch (eConnectException exc)
            {
                Console.WriteLine(exc.Message);
                return "eConnect Exception - " + exc.Message;
            }            
            catch (CommunicationObjectFaultedException cofe)
            {
                return "Communication Exception - " + cofe.Message;
            }
            catch (Exception ex)
            {
                return "Exception - " + ex.Message;
            }
            //finally
            //{
            //    // Release the resources of the eConnectMethods object
            //    requester.Dispose();
            //}
        }