试图重新连接到数据库

本文关键字:数据库 重新连接 | 更新日期: 2023-09-27 18:13:01

应用程序执行大量数据库查询。请求是在事件发生后由用户或通过使用多个计时器(10秒滴答)创建的。

数据库服务器突然不可用。这会导致屏幕上出现大量包含连接错误信息的消息。

我想实现这样一种情况,在这种情况下,一个失败的开放调用将冻结应用程序,并打开一个窗口,该窗口表明连接尝试每隔X秒重新尝试一次(加上一个进度条)。如果连接恢复,窗口将关闭,应用程序将解锁。

怎么做?请给出假设/指导方针或现成解决方案的示例。

试图重新连接到数据库

如果我没理解错的话,这是一个可用性问题。你的目标是让你的用户快乐。确信一切正常,同时等待数据库连接。你不希望:恐慌的用户随意按下按钮,打电话寻求帮助和抱怨。你肯定不想看到大量无意义的技术错误信息;也不是一个没有消息的冻结应用程序。但你会接受一个暂时冻结的应用程序,上面有一个很好的帮助信息。

好的可用性并不便宜。如果你想允许用户取消,那么你必须学习一些多线程。为此,我从这里开始:http://msdn.microsoft.com/en-us/library/ms951089.aspx。如果您对静态消息"请等待,数据库连接可能需要xxx秒…"感到满意,则可以避免此问题。

我大胆猜测你的WinForms应用程序从很多地方调用数据库,但你想要一些不需要几天重写的东西。

我能想到的最简单的单线程解决方案是定义一个PleaseWaitForm和一个'wrapper'方法,我将调用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";
    }
}
}