该应用程序需要大量的数据库查询。请求是在用户发出事件之后或通过使用几个计时器(10 秒滴答)创建的。
当数据库服务器突然变得不可用时,就会出现此问题。这会导致大量屏幕消息,其中包含有关连接错误的信息。
我想实现这样一种情况,其中失败的打开调用将冻结应用程序并打开一个窗口,该窗口指示将每 X 秒重试一次连接尝试的问题(加上一个进度条)。如果连接恢复,窗口关闭,应用程序将解锁。
怎么做?请假设/指导或现成解决方案的例子。
该应用程序需要大量的数据库查询。请求是在用户发出事件之后或通过使用几个计时器(10 秒滴答)创建的。
当数据库服务器突然变得不可用时,就会出现此问题。这会导致大量屏幕消息,其中包含有关连接错误的信息。
我想实现这样一种情况,其中失败的打开调用将冻结应用程序并打开一个窗口,该窗口指示将每 X 秒重试一次连接尝试的问题(加上一个进度条)。如果连接恢复,窗口关闭,应用程序将解锁。
怎么做?请假设/指导或现成解决方案的例子。
所以如果我理解正确,这是一个可用性问题。您的目标是让您的用户在等待数据库连接时感到高兴和自信,一切都很好。你不希望:恐慌的用户随意按下按钮、打电话寻求帮助和抱怨。你不想要一堆毫无意义的技术错误信息;也不是没有消息的冻结应用程序。但是你会接受一个带有很好帮助信息的暂时冻结的应用程序。
良好的可用性并不便宜。如果你想让用户取消,那么你必须学习一些多线程。为此,我将从这里开始: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";
}
}
}