我有一个c#winforms应用程序,我用来调用ASP.net webservice方法来做一些db。
...
namespace WebServiceClient
{
public partial class Form1 : Form
{
Service1ref.Service1 wbsrv = new Service1ref.Service1();
bool lbl_hid = true;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void button1_Click(object sender, EventArgs e)
{
label3.ForeColor = System.Drawing.Color.Azure;
label3.Text = "Request sent...";
wbsrv.Url = textBox1.Text;
string response = wbsrv.GenerateRandomSensorData(textBox2.Text);
label3.Text = response;
if (label3.Text.Contains('7'))
label3.ForeColor = System.Drawing.Color.Green;
else
label3.Text = "Error";
label3.ForeColor = System.Drawing.Color.Red;
if (lbl_hid == true)
{
label3.Show();
lbl_hid = false;
}
}
...
大多数情况下整个过程太快而"Request sent.."
部分甚至没有显示出来。我想在那里放一个小延迟,这样如果响应速度超过1秒,它应该等待整整秒,然后再下载代码。每次点击后,发送按钮也应停用3秒钟。我需要计时器吗?我试图完成某件事,但对我来说太难了。
答案 0 :(得分:2)
您可以使用3,000毫秒的计时器。单击该按钮时,禁用该按钮并启动计时器。计时器有一个名为TimeElapsed的事件,您需要订阅该事件,因为您需要再次激活该按钮。
答案 1 :(得分:2)
将button1处理程序标记为async
,然后使用await Task.Delay()
,如下所示:
private async void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
label3.ForeColor = System.Drawing.Color.Azure;
label3.Text = "Request sent...";
wbsrv.Url = textBox1.Text;
string response = wbsrv.GenerateRandomSensorData(textBox2.Text);
await Task.Delay(1000);
label3.Text = response;
if (label3.Text.Contains('7'))
{
label3.ForeColor = System.Drawing.Color.Green;
}
else
{
label3.Text = "Error";
label3.ForeColor = System.Drawing.Color.Red;
}
if (lbl_hid == true)
{
label3.Show();
lbl_hid = false;
}
await Task.Delay(2000);
button1.Enabled = true;
}
请注意,无论请求实际占用多长时间,都会等待一秒钟......并在重新启用按钮之前再强制等待两秒钟。
答案 2 :(得分:1)
您可能希望更聪明一点,并减少在3秒钟等待时调用Web服务所花费的时间。所以它不是WS Call + 3秒。
private async void button1_Click(object sender, EventArgs e)
{
//Record the time when button was clicked
DateTime timeButtonWasClicked = DateTime.Now;
button1.Enabled = false;
label3.ForeColor = System.Drawing.Color.Azure;
label3.Text = "Request sent...";
//Force the label to be repainted
label3.Invalidate();
wbsrv.Url = textBox1.Text;
string response = wbsrv.GenerateRandomSensorData(textBox2.Text);
//If the user has waited less than 3 seconds,
//make them wait the difference, otherwise
//dont force users to wait at least 6 or so seconds
TimeSpan ts = DateTime.Now - timeButtonWasClicked;
if (ts.Seconds < 3) await Task.Delay(TimeSpan.FromSeconds(3).Subtract(ts));
label3.Text = response;
if (label3.Text.Contains('7')) {
label3.ForeColor = System.Drawing.Color.Green;
}
else {
label3.Text = "Error";
label3.ForeColor = System.Drawing.Color.Red;
}
if (lbl_hid) { //Dont bother testing Booleans for "== true"
label3.Show();
lbl_hid = false;
}
button1.Enabled = true;
}
修改强>
请注意,我不支持这种方法,它非常hackish,如果你没有阅读使用业务逻辑层和C#控件绑定,它将导致非常糟糕的编程实践。我提供这个编辑以帮助您继续前进并了解更多信息。 我没有IDE就写过这个,所以可能有错误。
//Declare a timer control
private static System.Timers.Timer aTimer;
//We need to check when the response is populated between two methods, so I've declared it as a private member variable
private string response = string.Empty;
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
label3.ForeColor = System.Drawing.Color.Azure;
label3.Text = "Request sent...";
//Force the label to be repainted
label3.Invalidate();
//Instantiate the timer and set a one second interval.
aTimer = new System.Timers.Timer();
aTimer.Interval = 1000;
// Hook up the Elapsed event for the timer.
aTimer.Elapsed += OnTimedEvent;
// Start the timer
aTimer.Enabled = true;
wbsrv.Url = textBox1.Text;
response = wbsrv.GenerateRandomSensorData(textBox2.Text);
}
private static void OnTimedEvent(Object source, System.Timers.ElapsedEventArgs e)
{
//Check the response string variable is NOT empty
if (!string.IsNullOrEmpty(response))
{
label3.Text = response;
// Stop the timer
aTimer.Enabled = false;
}
else
{
return;
}
if (label3.Text.Contains('7')) {
label3.ForeColor = System.Drawing.Color.Green;
}
else {
label3.Text = "Error";
label3.ForeColor = System.Drawing.Color.Red;
}
if (lbl_hid) {
label3.Show();
lbl_hid = false;
}
button1.Enabled = true;
}
答案 3 :(得分:1)
await Task.Delay()是最好的解决方案。如上。 我没有异步等待时尝试的替代方法,并且由于某些原因无法更新.net框架和visual studio。
private void button1_Click(object sender, EventArgs e)
{
button1.Enabled = false;
label3.ForeColor = System.Drawing.Color.Azure;
label3.Text = "Request sent...";
wbsrv.Url = textBox1.Text;
string response = wbsrv.GenerateRandomSensorData(textBox2.Text);
// Custom Task Class
Task.Delay(TimeSpan.FromSeconds(1)).ContinueWith(AfteDelay);
}
private void AfterDelay(){
label3.Text = response;
if (label3.Text.Contains('7'))
{
label3.ForeColor = System.Drawing.Color.Green;
}
else
{
label3.Text = "Error";
label3.ForeColor = System.Drawing.Color.Red;
}
if (lbl_hid == true)
{
label3.Show();
lbl_hid = false;
}
button1.Enabled = true;
}
自定义任务类将如下所示。
using System.Windows.Forms.Timer;
public class Task
{
Timer timer;
public static Task Delay(TimeSpan timeSpan)
{
Task task = new Task();
task.timer = new Timer();
task.timer.Interval = Convert.ToInt32(timeSpan.TotalMilliseconds);
return task;
}
private Task()
{
}
public static Task Delay(int miliSeconds)
{
Task task = new Task();
task.timer = new Timer();
task.timer.Interval = miliSeconds;
return task;
}
public static void Run(Action action)
{
Timer timer = new Timer();
timer.Interval = 1;
timer.Enabled = true;
timer.Tick += delegate
{
timer.Stop();
timer = null;
action();
};
}
EventHandler elapsed;
public void ContinueWith(Action action)
{
timer.Enabled = true;
elapsed = delegate
{
Stop();
action();
};
//bind the event
timer.Tick += elapsed;
}
private void handleEvent(Action action)
{
}
public void Stop()
{
timer.Stop();
timer.Enabled = false;
//unbind the event
if (elapsed != null)
{
timer.Tick -= elapsed;
}
}
}