我对下面的代码有一些问题。
当应用程序运行时,一旦LookingAwayResult.Text = "Yes"
,计时器就会启动并计数到10。当LookingAwayResult.Text = "No"
或"Maybe"
时,计时器应停止并再次重置为0,但实际情况并非如此。
当计时器达到10时,会出现一个消息框,这正是我想要的,但这将继续显示并在我的屏幕上发送垃圾邮件。计时器将在消息框出现后重置回0,并且应用程序将冻结,直到在消息框上选择"确定"。
我的代码似乎在循环所有的计时器,这不是我想要的。
private void OnFaceFrameArrived(object sender, FaceFrameArrivedEventArgs e)
{
// Retrieve the face reference
FaceFrameReference faceRef = e.FrameReference;
if (faceRef == null) return;
// Acquire the face frame
using (FaceFrame faceFrame = faceRef.AcquireFrame())
{
if (faceFrame == null) return;
// Retrieve the face frame result
FaceFrameResult frameResult = faceFrame.FaceFrameResult;
// Display the values
HappyResult.Text = frameResult.FaceProperties[FaceProperty.Happy].ToString();
EngagedResult.Text = frameResult.FaceProperties[FaceProperty.Engaged].ToString();
GlassesResult.Text = frameResult.FaceProperties[FaceProperty.WearingGlasses].ToString();
LeftEyeResult.Text = frameResult.FaceProperties[FaceProperty.LeftEyeClosed].ToString();
RightEyeResult.Text = frameResult.FaceProperties[FaceProperty.RightEyeClosed].ToString();
MouthOpenResult.Text = frameResult.FaceProperties[FaceProperty.MouthOpen].ToString();
MouthMovedResult.Text = frameResult.FaceProperties[FaceProperty.MouthMoved].ToString();
//initilize look away timer for 10 seconds
Timer lookAwayTimer = new Timer(interval: 10000);
//inialize the poll tiomer for 50 ms
Timer pollTimer = new Timer(interval: 50);
LookingAwayResult.Text = frameResult.FaceProperties[FaceProperty.LookingAway].ToString();
//if 10 seconds expires then show message box
lookAwayTimer.Elapsed += (s, f) =>
{
MessageBox.Show("Looking is set to yes", "Looking Error", MessageBoxButton.OK);
};
//enable poll timer
pollTimer.Enabled = true;
//check if person is looking. If they are not then enable the lookAwayTimer. If they start looking
//then disable the timer
pollTimer.Elapsed += (s, f) =>
{
Check = frameResult.FaceProperties[FaceProperty.LookingAway].ToString();
if (Check == "Yes")
{
lookAwayTimer.Enabled = true;
}
else
{
lookAwayTimer.Enabled = false;
}
};
}
}
我所追求的是在该人不看后运行计时器,并在该人再次看时停止并重置为0。
当计时器达到10秒时,将出现消息框,应用程序将冻结。用户必须选择"确定",此框将消失,应用程序将重置回默认值。
根据研究,我相信使用全局变量或模态框可能会在这里派上用场?
我相信有了模态框,这会冻结我的应用程序,直到用户对它做了什么?但这仍然不能解决我的问题,即计时器没有重置回0,并且希望应用程序在选择"确定"后完全重置。
我也喜欢C#中的全局变量,除非必要,否则应该避免。
如果模态框是其中一部分的答案,我会把MessageBox.Show
改为ShowDialog
吗?
从您的问题中可以清楚地看出,您没有控制点击消息框按钮的任何操作。您可以显示消息框,仅用于通知用户。
因此,为了使代码在执行时不暂停,请在different thread
上创建消息框,这样执行就不会暂停。
下面的代码在单独的线程上创建一个消息框。
public class ThreadIndependentMB
{
private readonly Dispatcher uiDisp;
private readonly Window ownerWindow;
public ThreadIndependentMB(Dispatcher UIDispatcher, Window owner)
{
uiDisp = UIDispatcher;
ownerWindow = owner;
}
public MessageBoxResult Show(string msg, string caption="",
MessageBoxButton buttons=MessageBoxButton.OK,
MessageBoxImage image=MessageBoxImage.Information)
{
MessageBoxResult resmb = new MessageBoxResult();
if (ownerWindow != null)
uiDisp.Invoke(new Action(() =>
{
resmb = MessageBox.Show(ownerWindow, msg, caption, buttons, image);
}));
else
uiDisp.Invoke(new Action(() =>
{
resmb = MessageBox.Show( msg, caption, buttons, image);
}));
return resmb;
}
}
在计时器中,您可以实例化该类并调用该类的Show方法。
计时器上的AutoReset属性可以解决您的问题:
System.Timers.Timer lookAwayTimer = new System.Timers.Timer(10000)
{
AutoReset = false
};
lookAwayTimer.Elapsed += (object sender, System.Timers.ElapsedEventArgs e) =>
{
pollTimer.Stop();
MessageBox.Show("Looking is set to yes", "Looking Error", MessageBoxButtons.OK);
lookAwayTimer.Start();
pollTimer.Start();
};
将此设置为false将导致计时器经过一次,然后停止重复(这样它就不会垃圾邮件你的屏幕),直到你再次启动它-默认值为true,因此它将保持自动重置,并每10秒调用一次此方法。