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