我正在尝试将后台应用程序集成到需要同时运行的前台应用程序中 我一直在阅读许多Microsoft文档,似乎我无法理解它们的含义。我是XAML的初学者。这应该是覆盆子pi,背景代码用于传感器,而前景应该有按钮,用户可以点击OTP,如果他们没有RFID.OTP我可以管理,但我是有问题将背景整合到XAML中 我对此过分强调。请帮帮我
更新:
我明天会在Pi上尝试你的建议,希望它会起作用:)
private void OnPageLoaded(object sender, RoutedEventArgs e)
{
int interval = 20;
DateTime dueTime = DateTime.Now.AddMilliseconds(interval);
while (true)
{
if (DateTime.Now >= dueTime)
{
//insert code here
initComms();
StartUart();
//self monitoring
startLightMonitoring();
//Initial State
CurMode = Neutral;
Debug.WriteLine("===Entering MODE_SENDLIGHT===");
// This make sure the main program run idefinitely
while (true)
{
Sleep(300);
//state machine
handleModeSendLight();
if (CurMode == Neutral)
{
MailBoxMonitoring();
}
else if (CurMode == AccessMode)
{
AccessGranted();
}
else if (CurMode == IntrusionMode)
{
InvalidAccess();
}
else
{
Debug.WriteLine("Config Error");
}
//Update next dueTime
dueTime = DateTime.Now.AddMilliseconds(interval);
}
}
else
{
//Just yield to not tax out the CPU
Sleep(1);
}
}
}
答案 0 :(得分:0)
<强> MVVM:强>
您正在使用XAML和UWP。这意味着您应该使用MVVM模式。虽然您可以使用其他方法,但XAML和WPF / UWP在设计时考虑了MVVM。你失去了大约90%的XAML功能,并且由于不使用MVVM而遇到了大量的附加问题。几年前我写了一篇介绍: https://social.msdn.microsoft.com/Forums/vstudio/en-US/b1a8bf14-4acd-4d77-9df8-bdb95b02dbe2/lets-talk-about-mvvm?forum=wpf
后台操作:
在.NET中进行多任务/ - 线程的方法有很多种。 BackgroundWorker,Async ...等待,任务,线程化你在上面的评论中链接的内容。对于初学者,我会建议后台工作者,我为此编写了一个示例代码。但你的情况并不是初学者的水平:
#region Primenumbers
private void btnPrimStart_Click(object sender, EventArgs e)
{
if (!bgwPrim.IsBusy)
{
//Prepare ProgressBar and Textbox
int temp = (int)nudPrim.Value;
pgbPrim.Maximum = temp;
tbPrim.Text = "";
//Start processing
bgwPrim.RunWorkerAsync(temp);
}
}
private void btnPrimCancel_Click(object sender, EventArgs e)
{
if (bgwPrim.IsBusy)
{
bgwPrim.CancelAsync();
}
}
private void bgwPrim_DoWork(object sender, DoWorkEventArgs e)
{
int highestToCheck = (int)e.Argument;
//Get a reference to the BackgroundWorker running this code
//for Progress Updates and Cancelation checking
BackgroundWorker thisWorker = (BackgroundWorker)sender;
//Create the list that stores the results and is returned by DoWork
List<int> Primes = new List<int>();
//Check all uneven numbers between 1 and whatever the user choose as upper limit
for(int PrimeCandidate=1; PrimeCandidate < highestToCheck; PrimeCandidate+=2)
{
//Report progress
thisWorker.ReportProgress(PrimeCandidate);
bool isNoPrime = false;
//Check if the Cancelation was requested during the last loop
if (thisWorker.CancellationPending)
{
//Tell the Backgroundworker you are canceling and exit the for-loop
e.Cancel = true;
break;
}
//Determin if this is a Prime Number
for (int j = 3; j < PrimeCandidate && !isNoPrime; j += 2)
{
if (PrimeCandidate % j == 0)
isNoPrime = true;
}
if (!isNoPrime)
Primes.Add(PrimeCandidate);
}
//Tell the progress bar you are finished
thisWorker.ReportProgress(highestToCheck);
//Save Return Value
e.Result = Primes.ToArray();
}
private void bgwPrim_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
pgbPrim.Value = e.ProgressPercentage;
}
private void bgwPrim_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
pgbPrim.Value = pgbPrim.Maximum;
this.Refresh();
if (!e.Cancelled && e.Error == null)
{
//Show the Result
int[] Primes = (int[])e.Result;
StringBuilder sbOutput = new StringBuilder();
foreach (int Prim in Primes)
{
sbOutput.Append(Prim.ToString() + Environment.NewLine);
}
tbPrim.Text = sbOutput.ToString();
}
else
{
tbPrim.Text = "Operation canceled by user or Exception";
}
}
#endregion
&#13;
GUI写入开销:
您的案例很棘手,因为您需要一个几乎永久运行的线程,并且大部分工作都是通过Progress Reporting完成的。问题在于编写GUI非常昂贵。如果每个用户启动事件只执行一次,那么这并不重要,但是在这里你有一个循环(在另一个线程或任务中)重复写入(通过更改通知或直接)。您可以通过太多更改完全重载GUI线程。事实上,我上面代码的原始变体就是这样:我试图通过Progress报告分发每个找到的素数,然后将它附加到输出框。在一个足够大的上限,它发现了如此多的素数如此之快,将它们附加到输出框的字符串完全对GUI线程征税了一段时间。由于素数变得罕见,GUI线程设法赶上。但是,您的数据收集将始终以相同的速度运行。我也为这个问题写了一个例子:
using System;
using System.Windows.Forms;
namespace UIWriteOverhead
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
int[] getNumbers(int upperLimit)
{
int[] ReturnValue = new int[upperLimit];
for (int i = 0; i < ReturnValue.Length; i++)
ReturnValue[i] = i;
return ReturnValue;
}
void printWithBuffer(int[] Values)
{
textBox1.Text = "";
string buffer = "";
foreach (int Number in Values)
buffer += Number.ToString() + Environment.NewLine;
textBox1.Text = buffer;
}
void printDirectly(int[] Values){
textBox1.Text = "";
foreach (int Number in Values)
textBox1.Text += Number.ToString() + Environment.NewLine;
}
private void btnPrintBuffer_Click(object sender, EventArgs e)
{
MessageBox.Show("Generating Numbers");
int[] temp = getNumbers(10000);
MessageBox.Show("Printing with buffer");
printWithBuffer(temp);
MessageBox.Show("Printing done");
}
private void btnPrintDirect_Click(object sender, EventArgs e)
{
MessageBox.Show("Generating Numbers");
int[] temp = getNumbers(1000);
MessageBox.Show("Printing directly");
printDirectly(temp);
MessageBox.Show("Printing done");
}
}
}
&#13;
有两种解决方法:
integer interval = 20;
DateTime dueTime = DateTime.Now.AddMillisconds(interval);
while(true){
if(DateTime.Now >= dueTime){
//insert code here
//Update next dueTime
dueTime = DateTime.Now.AddMillisconds(interval);
}
else{
//Just yield to not tax out the CPU
Thread.Sleep(1);
}
}
&#13;