1

MySQL データベースからデータを取得してコンソール ウィンドウに表示するインターフェイスがあります。情報を表示するために使用されるコードは、while ループを使用して循環されます。

私が抱えている問題は、MySQL 接続が各ループで開いたり閉じたりするため、情報の表示に遅延が生じることです。ループの前に接続を開き、ループが終了したら閉じようとしましたが、接続が有効で開いている必要があるという例外が表示されます。

したがって、ループはデータベースからdatalistリストにデータを追加し、コンソールに表示します。サーバー上の情報は更新によって変更される可能性があるため、ループごとにリストもクリアされます。

私が避けたいもう1つのことはThread.Sleep()、プログラムがハングすることです(私が知っているように設計されています)が、他の解決策はわかりません。

これが私のコードです。

public void Loop()
    {
        public static string loopquery;
        public static List<DataList> datalist;

        var cki = new ConsoleKeyInfo();

        do
        {
            DateTime time = DateTime.Now.AddSeconds(1);

            while ((DateTime.Now < time))
            {
                Console.Clear();
                Travel.data.Clear();

                loopquery = "SELECT * FROM database)";
                Travel();

                Console.WriteLine("Hurray it's a loop!");
                Console.WriteLine(datalist[0].id);
                Console.WriteLine(datalist[0].name);

                if (Console.KeyAvailable)
                {
                    // Waits until the user presses a key, and puts it into our object key.
                    cki = Console.ReadKey(true);

                    if (cki.Key == ConsoleKey.UpArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.DownArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.LeftArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.RightArrow)
                    {
                        // Do Something
                    }
                    if (cki.Key == ConsoleKey.Escape)
                    {
                        break;
                    }
                }
                else
                {
                    Thread.Sleep(1000);
                }

            }
        } while (cki.Key != ConsoleKey.Escape);
    }

public void Travel()
    {
        //Open a connection
        databaseCon.Open();

        //Create Command
        var cmd = new MySqlCommand(Loop.loopquery, databaseCon);

        //Create a data reader and Execute the command
        var dataReader = cmd.ExecuteReader();

        try
        {
            //Read the data and store them in the list
            while (dataReader.Read())
            {
                 var data= new DataList();
                    data.id = (dataReader.GetInt32(0));
                    data.name = (dataReader.GetString(1));

                    Loop.datalist.Add(data);
            }
        }
        catch (MySqlException ex)
        {
            Console.WriteLine("Error: {0}", ex);
            Console.ReadLine();
        }
        finally
        {
            if (dataReader != null)
            {
                //close Data Reader
                dataReader.Close();
            }

            if (databaseCon != null)
            {
                //close Connection
                databaseCon.Close();
            }
        }
    }

これを行うより効率的な方法はありますか?このクライアントは多くの人が使用するため、何百ものクエリでサーバーを攻撃したくありません。

4

1 に答える 1

1

ご指摘のとおり、多くのクライアントにとって、ループ内のデータベースに対して直接何百ものクエリを実行するのは効率的ではない可能性があります。

アプリの詳細はありませんが、多数のクライアントがループで SQL サーバーを攻撃するのを回避する 1 つの方法は、クライアントとデータベース サーバーの間にアプリケーション層を追加することです。クライアントが照会する API エンドポイント (REST など) を開くことができます。アプリケーション層サーバーは定期的にクエリを実行し、すべてのクライアントがクエリできるようにメモリ内にデータを保持できます。

もちろん、これは、多くのクライアントが同じデータにアクセスして共有している場合、またはキャッシュ可能なデータ セットをメモリに保持できる場合にのみ意味があります。また、キャッシュまたは更新からデータを削除する必要がある時期を決定するために、そのデータがどの程度潜在的であるかにも依存します。

さらに別のオプションは、データが変更されたときにサーバーがクライアントにコールバックするソケットサーバーのようなものとの双方向通信を作成することです。

アプリケーション層が書き込みにも使用される場合、変更時にキャッシュ内のデータを無効にする他のオプションがあります。

于 2012-12-23T21:00:33.567 に答える