Windows Phone 8.1 Modal Dialog. How? - c#

Following examples here in Stack Overflow, I put together a MessageDialog to show my user error messages.
In the emulator, it works fine.
On the phone, it blows right through, flashes the MessageDialog on the screen for only a moment, and even blows through a Task.Delay I put in as a workaround.
Would somebody please explain to me what's happening, or point me in the right direction?
p.s. I also tried a ContentDialog per an article here. THAT doesn't even display the message text.
Here's a code snippet:
public static async void ShowAndGo (String MessCode, String MessText, Boolean Xit)
{
String Mess = ""; // Start out with an empty Message to tell Joe User.
String Title = ""; // And an empty title too.
if (MessCode != "") // If we're sent a Message "Code,"
Mess = App.ResLdr.GetString (MessCode) + Cx.ld + Cx.ld; // turn it into text, culturally-aware.
Mess += MessText; // Stick MessText onto the end of it.
if (Xit)
Title = App.ResLdr.GetString ("OhSnap"); // If we're goin' down, curse a little.
else
Title = App.ResLdr.GetString ("NoProb"); // If it's just informational, no problem-o.
MessageDialog messageDialog = new MessageDialog (Mess, Title);
await messageDialog.ShowAsync (); // IT FREAKING ISN'T STOPPING HERE!!!
Task.Delay (10000).Wait (); // Wait 10 seconds with error message on the screen.
// AND IT FREAKING DOESN'T STOP HERE EITHER!!!
}

The reason of your problem is simple - you are declaring async void method - avoid that, this should be used only in special cases, for example events. In the code you have, your program doesn't stop on line where you invoke the method:
ShowAndGo("Message code", "Message Text", false);
Debug.WriteLine("Something happening");
It probably shows a message, but how long it will survive it depends on your further code. The remedy for this is to change the method from void to Task and await:
public static async Task ShowAndGo (String MessCode, String MessText, Boolean Xit)
{ /* method */ }
//invoke:
await ShowAndGo("Message code", "Message Text", false);
Debug.WriteLine("Something happening"); // now it should wait till user clicks OK
Of course that requires async all the way, but probably that's how your program should look like.

Related

C# winforms freezing: Serialport, Timer, Thread

Edit: Keeping the original question for continuity.
I then edited the question with replacement code for the ReadLine() method by using ReadExisting instead. It works however I still have the same freeze, where the app becomes unresponsive. Debug says it's locking (it takes a while to freeze, sometimes seconds, sometimes minutes) in the while () {} function where I wait for the complete message. More explanations below:
-- obsolete --
What is a good way to handle serialport.readtimeout exception?
try
{
serialPort1.Write(Command_);
if (!IsWriteComm_)
{
Response_ = serialPort1.ReadLine().Replace("\r", "");
}
}
catch (TimeoutException err)
{
DateTime d = DateTime.Now;
rtboxDiag.AppendText("\n" + d.ToString("HH:mm:ss") + ": ");
rtboxDiag.AppendText(err.Message);
if (!serialPort1.IsOpen)
InitConnection();
return Textbox_;
}
this bit of code is exectuted on a timer tick event.
I was having a weird "crash" of the app with an IO exception
"The I/O operation has been aborted because of either a thread exit or an application request."
no matter what I do I am not able to "recover" meaning, I am no longer able to poll data from the serial port.
I added this exception catch and it does log the exception. weirdly enough the test on !serialport.isopen is false (meaning the port is still open).
What might be a hint is: this error does STOP the timer somehow, this is not something I am doing in code. so I am suspecting something related to the timer, rather than the serialport, but I could be wrong.
Closing the port manually, and reconnecting does not fix the problem.
Disconnecting and reconnecting the USB does not fix the problem.
however, closing the app, and relaunching the app does fix the problem (without even disconnecting the MCU or power cycling the MCU/hardware).
-- /obsolete --
edit: the problem is appearing after a few seconds, sometimes minutes of flawless operations. I cannot repeat the issue using a serialport terminal polling the data the same way, at the same frequency. It seems the problem is not coming from the hardware itself.
cheers
Edit: I have yet to test the following modification, not sure if it will fix this problem (I doubt), but at least it's an attempt at not using .readline() which from what I've gathered is not good practice.
anyway here it is:
try
{
serialPort1.Write(Command_);
if (!IsWriteComm_)
{
while (!SerialRxCplt) ;
Response_ = SerialRxResponse.Replace("\r", "").Replace("\n", "");
SerialRxCplt = false;
//Response_ = serialPort1.ReadLine().Replace("\r", "");
}
}
catch (TimeoutException err)
{
DateTime d = DateTime.Now;
rtboxDiag.AppendText("\n" + d.ToString("HH:mm:ss") + ": ");
rtboxDiag.AppendText(err.Message);
if (!serialPort1.IsOpen)
InitConnection();
return Textbox_;
}
and I have the datareceived event enabled:
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
var serialPort = (System.IO.Ports.SerialPort)sender;
string dataReceived = serialPort.ReadExisting();
ProcessSerialData(dataReceived);
}
and this is how I am processing the data, and manually "waiting" for the \n character which tells me when the data has been fully received.
private void ProcessSerialData(string data)
{
SerialRxBuffer += data;
if (SerialRxBuffer.Contains("\n"))
{
SerialRxCplt = true;
SerialRxResponse = SerialRxBuffer;
SerialRxBuffer = "";
}
else
{
SerialRxCplt = false;
}
}
any input is welcome.
I have added "stuff" for debugging inside that while loop and it does work fine for a while and then freezes, no error or exception is thrown there. For some reason I have a feeling it's not related to the serial port.
I have even added this:
try
{
serialPort1.Write(Command_);
if (!IsWriteComm_)
{
Stopwatch stopWatch = new Stopwatch();
stopWatch.Start();
while (!SerialRxCplt || Timer2StopWatchMilli > 5)
{
Timer2StopWatchMilli = stopWatch.Elapsed.TotalMilliseconds;
ExceptionMessage = Timer2StopWatchMilli.ToString();
IsException = true;
}
stopWatch.Stop();
if (!SerialRxCplt)
return Textbox_;
Response_ = SerialRxResponse.Replace("\r", "").Replace("\n", "");
SerialRxCplt = false;
//Response_ = serialPort1.ReadLine().Replace("\r", "");
}
}
the ExceptionMessage and IsException help me have an idea of what's happening in that loop. And in normal operations, it is what you would except, increments in the order of 0.0x milliseconds. Data is being processed correctly. When it freezes, nothing looks abnormal. I initially thought I was somehow getting "stuck" in an infinite loop but that || Timer2StopWatchMilli > 5 should get me out of it, acting as some sort of timeout.
one extra piece of info: when it freezes, the one CPU core is fully loaded. (I have a 6core CPU, and it's 16-17% in the task manager - memory usage is low < 30MB)
Any help is welcome
I fixed it by clearing RX/TX and stream buffers after each successful transaction.
I think data was being sent to the PC faster than it was able to read causing data to eventually accumulating on the Rx Buffer.
private void SerialPortClearBuffers()
{
serialPort1.DiscardOutBuffer();
serialPort1.DiscardInBuffer();
serialPort1.BaseStream.Flush();
}

How can i answer "CallbackData" without use "AnswerCallbackQueryAsync" in telegram bot (C#)

the main problem is i want to send answer to user without showing by
notification or alert in telegram , and i want to show message in main
panel like other messages.
This line of code just fire a notification
await api.AnswerCallbackQueryAsync(update.CallbackQuery.Id,"text");
How can i response to callback like this line code?
await api.SendTextMessageAsync(update.Message.Chat.Id,"text");
You should use that because this will stop loading GIF from telegram.
If you don't want to show alert, Leave text parameter null and it won't show alert.
then use SendTextMessageAsync method to send message to other messages.
Your code should be like this:
private void Bot_OnCallbackQuery(object sender, CallbackQueryEventArgs e)
{
if (e.Query.Data == "Hello")
{
string reply = "Hi!";
// Answer with null parameter:
await Bot.AnswerCallbackQuery(e.Query.Id, null);
// Reply with message instead:
await Bot.SendTextMessageAsync(e.Query.Message.Chat, reply);
}
}

MS Bot Framework stuck sending messages in an infinite loop

My bot that uses MS Bot Framework is stuck sending messages to the user in an infinite loop, both on the facebook and emulator channels.
My bot has a "root" IDialog, kind of like a menu, that calls a few other IDialogs depending on the user's selection. The child dialogs are called in this way:
...
else if (response.Text == MainOptions[2])
{
await context.Forward(new InfoCounterDialog(), ChildDialogComplete,
response, CancellationToken.None);
}
...
response is an IMessageActivity sent by user;
ChildDialogComplete is a method that builds the main menu again and ends with these lines:
.
await context.PostAsync(restartPrompt);
context.Wait(MainScreenSelectionReceived);
All dialogs work fine except this one very short dialog, which causes an infinite loop - the bot keeps sending this message again and again until I stop the web app.
namespace XXXX
{
[Serializable]
public class InfoCounterDialog : IDialog
{
public async Task StartAsync(IDialogContext context)
{
var hourNow = DateTime.Now.Hour;
var openNow = "";
if (hourNow >= 7)
{
openNow = "It is open now and will close at midnight.";
}
else
{
openNow = "It is closed now and will open at 7:00";
}
var card = HeroCardUtils.CardWithImageAndMiscButtons(
"Our information counter can help!",
"It's located in Shop 081, Level 3 in Building 2. " + openNow,
"http://www.[image URL here].jpg",
new[] { "More Details" },
new[] { ActionTypes.OpenUrl },
new[] { "[webpage URL here]" }
);
await BotUtils.SendCardToChat(context, card);
context.Done(this);
}
}
}
If you're wondering what SendCardToChat does:
public async static Task SendCardToChat(IDialogContext context, HeroCard card)
{
var activity = context.MakeMessage();
activity.Attachments = HeroCardUtils.CardToAttachments(card);
await context.PostAsync(activity);
}
To recap:
I'm launching a dialog from another dialog using context.Forward()
The dialog is supposed to show a message to the user and immediately terminate without extra input from user
Instead, it keeps sending the "Our information counter can help!" message infinitely.
My best guess is that the child dialog somehow returns the user's initial message to the conversation, which triggers the same dialog again and again. But this shouldn't happen, the child IDialog shouldn't send anything to the conversation except the HeroCard I created.
Or maybe I'm looking in a wrong direction and Bot Framework just doesn't support IDialogs that do something and immediately terminate without a context.Wait()?
I found that there isn't much documentation on context.Done(R value) but its really important in controlling the flow of the dialog.
I'm guessing that context.Done(this) calls your Dialog again? have you tried
context.Done(true);
I'm finding it frustrating that there isn't a context.Done() method (no parameter) to tell the dialog that your finished.
Further to this, i've found that in this Microsoft Example they use
// within a HotelsDialog.cs
context.Done<object>(null);
This is possible because they call the dialog from a root dialog
// within RootDialog.cs
context.Call(new HotelsDialog(), this.ResumeAfterOptionDialog);

WNS PushNotificationReceived does not intercept toast push notification

I'm writing a windows desktop app that relies on notifications to work. However, the event handler code, PushNotificationReceived on the channel does not seem to actually fire when I receive a notification. The following code is called to get the channel before its uri is sent to my server:
internal async Task<PushNotificationChannel> GetChannel()
{
PushNotificationChannel pnc;
try
{
pnc = await PushNotificationChannelManager.CreatePushNotificationChannelForApplicationAsync();
if (_channel == null || !pnc.Uri.Equals(_channel.Uri))
{
_channel = pnc;
_channel.PushNotificationReceived += OnPushNotificationReceived;
Debug.WriteLine(_channel.Uri);
}
}
catch (Exception ex)
{
Debug.WriteLine(ex.Message);
_channel = null;
}
dispatcher = Windows.UI.Core.CoreWindow.GetForCurrentThread().Dispatcher;
return _channel;
}
Such that anytime the channel is created or updated (via a different channel uri), it should assign the new channel's PushNotificationReceived event to the following (which is basically lifted from msdn's example):
void OnPushNotificationReceived(PushNotificationChannel sender, PushNotificationReceivedEventArgs e)
{
string typeString = String.Empty;
string notificationContent = String.Empty;
switch (e.NotificationType)
{
//
//other notification types omitted for brevity
//
case PushNotificationType.Toast:
notificationContent = e.ToastNotification.Content.GetXml();
typeString = "Toast";
// Setting the cancel property prevents the notification from being delivered. It's especially important to do this for toasts:
// if your application is already on the screen, there's no need to display a toast from push notifications.
e.Cancel = true;
break;
}
Debug.WriteLine("Received notification, with payload: {0}", notificationContent);
string text = "Received a " + typeString + " notification, containing: " + notificationContent;
var ignored = dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
{
MainPage.Current.ClearBanner();
});
}
Importantly, "MainPage.Current" is a reference to the app's main page as a static variable. The clear banner line simply removes a pink banner from the main page (just trying to get something simple working to start).
However, the code never seems to fire (no debug statement, pink banner remains). I am successfully getting the toast notification, and clicking on it will set focus to my app, so it's definitely not going to the wrong place.
Is there something I am doing wrong or some way to debug the notifications themselves?

C# autoit WinWaitActive not returning correct value

I'm trying to get the information from a Messagebox that appears after a process runs in the GUI that I'm controlling with AutoIt v3. The messagebox will either show a success message or a fail message and I want to log those outcomes, but it keeps going to the 'failed install' rather than the 'success' and notes it in the log as a failure when I can see the message says success. Any help is appreciated. Here's my code along with my commented thoughts:
internal void Install(string filepath)
{
au3.Send("!i"); //Send ALT+I
au3.WinWaitActive("Select Content Package", "", 20000); //Wait for window
au3.WinActivate("Select Content Package"); //If something else came up focus back on it prior to next line
au3.MouseClick("primary", 337,11); //Click on field as AutoIt cannot access it.
au3.Send(filepath);
au3.Send("{Enter}");
if(au3.WinWaitActive("Program", "successfully installed.", 90) == 1)
{ //WinWaitActive should return 1 if it is successful. The messagebox contains the text "successfully installed."
au3.Send("{Enter}");
writeLog(filepath + " Successfully installed.")
}
else
{ //WinWaitActive should return 0 if timeout, thus triggering this code
au3.Send("{Enter}");
writeLog(filepath + " Failed Install.")
}
}
I resolved my issue. The title in WinWaitActive() is case-sensitive and I missed a capitalization.

Categories