0

アプリケーションは多くのデータベース クエリを実行します。リクエストは、ユーザーが作成したイベントの後、または複数のタイマー (10 秒ティック) を使用して作成されます。

この問題は、データベース サーバーが突然使用できなくなったときに発生します。これにより、接続エラーに関する情報を含む大量のメッセージが画面に表示されます。

open 呼び出しが失敗するとアプリケーションがフリーズし、接続試行が X 秒ごとに再試行されるという問題を示す単一のウィンドウ (およびプログレス バー) が表示されるような状況を実現したいと考えています。接続が復元されると、ウィンドウが閉じられ、アプリケーションのロックが解除されます。

どうやってするの?仮定/ガイドラインまたは既製のソリューションの例をお願いします。

4

1 に答える 1

0

ですから、私があなたの言うことを正しく理解していれば、それはユーザビリティの問題です。あなたの目標は、データベース接続を待っている間、ユーザーが満足し、すべてがうまくいっていることを確信できるようにすることです。望まない: パニックに陥ったユーザーがランダムにボタンを押したり、電話で助けを求めたり、不満を言ったりします。意味のない技術的なエラー メッセージが大量に表示されるのは望ましくありません。メッセージのないフリーズしたアプリでもありません。しかし、役立つメッセージが表示された一時的に凍結されたアプリを受け入れることができます。

優れたユーザビリティは安くはありません。ユーザーがキャンセルできるようにする場合は、マルチスレッドについて学習する必要があります。そのために、ここから始めます: http://msdn.microsoft.com/en-us/library/ms951089.aspx。「しばらくお待ちください。データベース接続には最大 xxx 秒かかる場合があります...」という静的メッセージに問題がなければ、これを回避できます。

あなたの WinForms アプリは多くの場所からデータベースを呼び出していると思いますが、書き直しに何日もかからないものが必要です。

私が考えることができる最も単純なシングル スレッド ソリューションは、PleaseWaitForm と「ラッパー」メソッドを定義することです。これを DoWithPleaseWait() と呼びます。形:

namespace WinFormsPleaseWaitExample
{
//You don't need these 2 lines if you have .Net 3 or later
public delegate void Action(); 
public delegate TResult Func<TResult>();
//

public partial class Form1 : Form
{
    private readonly Form pleaseWaitForm;
    public Form1()
    {
        InitializeComponent();
        pleaseWaitForm = new PleaseWaitForm {Owner = this};
    }

    private void button1_Click(object sender, EventArgs e)
    {
        var result= DoWithPleaseWait(delegate { return SomeBusinessLayerClass.ADataRetrieval("boo"); });
        MessageBox.Show(result.ToString());
    }

    private void button2_Click(object sender, EventArgs e)
    {
        DoWithPleaseWait(delegate { SomeBusinessLayerClass.ADataOperation("boo"); });
    }

    public void DoWithPleaseWait(Action action)
    {
        pleaseWaitForm.Show();
        action.DynamicInvoke();
        pleaseWaitForm.Hide();
    }

    public TResult DoWithPleaseWait<TResult>(Func<TResult> func)
    {
        pleaseWaitForm.Show();
        TResult result = (TResult)func.DynamicInvoke();
        pleaseWaitForm.Hide();
        return result;
    }
}

public class SomeBusinessLayerClass
{
    public static void ADataOperation(string someInput)
    {
        //Do something that might take several seconds...
        Thread.Sleep(3000);
    }
    public static object ADataRetrieval(string someInput)
    {
        //Do something that might take several seconds...
        Thread.Sleep(3000);
        return someInput + " returned";
    }
}
}
于 2013-05-09T11:30:59.447 に答える