1

我正在使用 C# 开发 EConnect 集成 Windows 窗体应用程序。我在测试我的连接字符串时遇到了很多麻烦。基本上我让用户可以选择更改连接字符串,所以我希望能够对其进行测试。据我所知,EConnect 没有任何内置函数来测试连接,所以我正在编写一个非常粗糙的函数来自己做。仅供大家参考,连接字符串由 GP 数据库所在的服务器名称和数据库名称组成。

我认为实际测试函数的细节并不重要,但主要问题是在该函数中我调用了一个名为 getEntity 的 eConnect 方法,该方法使用连接字符串,如果连接字符串正确,它将提取信息。如果数据库名称错误,getEntity 方法将返回一个很容易捕获的 eConnect 异常,但是如果服务器名称错误,getEntity 方法只会旋转并且我的应用程序会卡住。

我正在尝试编写一些可以异步运行测试功能并同时检查超时或 econnect 异常的东西。这就是我卡住的地方,我一辈子都无法让它工作。这是我尝试的第一件事(这是在我的 TestConnection 方法中):

task = Task.Factory.StartNew(() => requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml), token);

try
{
    if (!task.Wait(timeOut, token))
    {
        Console.WriteLine("The server name is incorrect - task timed out");
        return false;
    }
}
catch (ThreadInterruptedException)
{
return false;
}
catch (AggregateException ae)
{
    ae.Handle((x) =>
    {
        if (x is eConnectException) // This we know how to handle.
        {
            Console.WriteLine("Incorrect Database Name! -- " + x.Message);
            return false;
        }
        return false; // Let anything else stop the application.
    });

}

这将捕获服务器错误以及我的 econnect 方法刚刚超时的情况。但它从未捕获到 eConnect 异常,Visual Studio 会破坏应用程序并告诉我我有一个未处理的异常。

这是我现在正在尝试的,这是我为我的表格准备的完整课程。在这里,我尝试使用 IAsyncResult 并使用 WaitHandle 检查函数是否完成或超时。这似乎有时有效,它适用于正确的字符串和数据库错误的情况,有时它适用于服务器错误的情况,但是一旦我测试了错误的服务器名称,它就不再适用于其他任何东西。有没有我遗漏的东西,或者有更好的方法在 TestGPConnection 中运行 getentity 方法并检查它是否在一段时间后没有完成,是否没有终止该方法并让用户重新输入服务器名称?

public partial class UpdateGPConnection : Form
{
    Task task;
    AsyncCallback cb;
    public delegate string startProcessToCall();
    startProcessToCall sp2c;       

    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);
        timer1.Enabled = true;

        Thread.Sleep(0);

        bool test = asyncResult.AsyncWaitHandle.WaitOne(15000);

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



        bool result = asyncResult.IsCompleted;

        asyncResult.AsyncWaitHandle.Close();

        this.Close();
    }



    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);

            string reqDoc = requester.GetEntity(GPCongfigSettings.GPConnectionString, myXmlDocument.OuterXml);

            return "Correct Connection";


        }
        catch (eConnectException exc)
        {
            Console.WriteLine(exc.Message);
            return "eConnect Excpetion";
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            return "Excpetion";
        }
    }

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


}
4

1 回答 1

1

您没有处理eConnectException. 您在 中显示一条消息,Console然后通过返回实质上重新抛出异常false

如果您确实处理了异常,那么您应该返回true以避免重新抛出它:

catch (AggregateException ae)
{
    ae.Handle((x) =>
    {
        if (x is eConnectException) // This we know how to handle.
        {
            Console.WriteLine("Incorrect Database Name! -- " + x.Message);
        }

        return x is eConnectException; //rethrow anything that is not an eConnectException
    });
}
于 2016-01-26T17:34:51.160 回答