CommunicationObjectFaultedException - System.ServiceModel.Ch
本文关键字:Ch ServiceModel System CommunicationObjectFaultedException | 更新日期: 2023-09-27 18:32:07
我正在研究 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 中释放请求者方法时,似乎总是发生错误。
任何想法我应该做什么?我整天都在谷歌上搜索这个,我对我发现的如何解决这个问题感到非常困惑。
尝试更改代码:
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();
//}
}