C# Speech Synthesis issue - c#

I have run into an issue that has thrown me for a loop since last night. I decided that in order for my program to be as user friendly as possible, I should do some exception handling so a user would know why it isn't working. However, No matter how I tried to catch the System.Argument Exception, it still would be thrown. I'm not looking for someone to just give me some code to fix this, I would really like someone to explain why this is happening so I know what to do to handle this sort of problem in the future.
using System.Speech.Synthesis;
namespace SpeechProject
{
/// <summary>
/// Interaction logic for EnglishChinese.xaml
/// </summary>
public partial class EnglishChinese : Page
{
public EnglishChinese()
{
InitializeComponent();
}
private void speakBtn_Click(object sender, RoutedEventArgs e)
{
SpeechSynthesizer synth = new SpeechSynthesizer();
try
{
synth.SelectVoice("Microsoft Hanhan Desktop");
synth.Speak(spokenWords.Text);
}
catch (ArgumentException)
{
MessageBox.Show("You need to install the China Chinese Simplified Language Pack to use this feature");
}
}
}
}
I then tried a different approach from this one. I tried an if else combination. Although, i'm pretty sure i'm not doing something correctly with that said if statement. But it does however work for using "Microsoft Zira Desktop" but does not work for the others.
public partial class EnglishChinese : Page
{
public EnglishChinese()
{
InitializeComponent();
}
private void speakBtn_Click(object sender, RoutedEventArgs e)
{
SpeechSynthesizer synth = new SpeechSynthesizer();
if (synth.Voice.Name == "Microsoft Huihui Desktop")
{
synth.SelectVoice("Microsoft Huihui Desktop");
synth.Speak(spokenWords.Text);
}
else
{
MessageBox.Show("You need to install the China Chinese Simplified Language Pack to use this feature");
}
}
}
}
// It automatically throws the message box, when I click the button
This is rather confusing since if it works for one, it should work for all, but that isn't the case with this if statement structure. Any tips would be very much appreciated.
Results with the catch Exception ex and Argument Exception ext:

Stewart_R, Psudonym and EBrown all helped answer this question.
Debug settings needed to be changed to reflect how I wanted certain exceptions to be handled. And the Try Catch method was the better method to use instead of the If Else statements. I had to make sure I caught the specific exception I wanted, in this case it was ArgumentException.
Thank you guys for your help. I really appreciate it.

Related

Unity functions called inside 'task.IsCompleted' stop program from continuing

I'm using Firebase Realtime Database to store a list of users and their friends for a game. Saving data has given me no problems but retrieving it has been giving me problems for a couple of days now. Whenever I retrieve data and call any Unity function (I've tested a PlayerPrefs.GetString() and Instantiate()), the program stops, without any error, but also lets me do other things because it's asynchronous (better explained by code below).
I've tried running it through a debugger and using a bunch of print statements to see what the problem is. However, the program doesn't give me any error so it's been impossible to debug it. I've just been guessing blindly.
I've managed to recreate the problem in the simplest way here:
using Firebase;
using Firebase.Database;
using Firebase.Unity.Editor;
using UnityEngine;
public class FirebaseData : MonoBehaviour {
private void Awake() {
PlayerPrefs.SetString("test", "hello");
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("HERE IS THE URL TO MY PROJECT");
TestRetrieve();
}
public void TestRetrieve() {
FirebaseDatabase.DefaultInstance.GetReference("users/").GetValueAsync().ContinueWith(task => {
if (task.IsFaulted) {
// Handle the error...
} else if (task.IsCompleted) {
DataSnapshot snapshot = task.Result;
print("here");
PlayerPrefs.GetString("test");
print("there");
}
});
}
}
You would expect the program to print "here" and then print "there". However, only "here" gets printed and then whatever code follows the "PlayerPrefs.GetString("test);" line will not ever be run. There is no errors given.
This is literally the only script in the project, just attached to an empty GameObject.
The weird part is that the print functions and most other ones not related to Unity but just pure c#, seem to be working. It's only the Unity functions which are giving me trouble.
Use async event handlers to allow for a better syntax flow.
public class FirebaseData : MonoBehaviour {
void Start() {
PlayerPrefs.SetString("test", "hello");
FirebaseApp.DefaultInstance.SetEditorDatabaseUrl("HERE IS THE URL TO MY PROJECT");
TestRetrieve();
}
public void TestRetrieve() {
retrieve += onRetrieve;
retrieve(this, EventArgs.Empty);
}
event EventHandler retrieve = delegate { };
private async void onRetrieve(object sender, EventArgs args) {
retrieve -= onRetrieve;
try {
DataSnapshot snapshot = await FirebaseDatabase.DefaultInstance.GetReference("users/").GetValueAsync();
print("here");
PlayerPrefs.GetString("test");
print("there");
} catch (Exception ex) {
// Handle the error here...
}
}
}
Reference Async/Await - Best Practices in Asynchronous Programming

if statement with no result in C# VS 2012

I have a code like this in VS 2012:
private void Form1_Load(object sender, EventArgs e)
{
if (Properties.Settings.Default["Database"] != null)
{
MessageBox.Show("We landed on spot 1");
}
else
{
MessageBox.Show("We landed on spot 2");
}
}
I'm pretty sure I messed up the condition syntax, but I would expect that one of these would happen:
Compiler warns about errors/project fails to run.
First message is shown
Second message is shown.
But neither of these actually happens. I've been staring at this for an hour and resources I could find are pretty slim.
If anyone with an experience could explain me what actually happens here?
Edit:
Thanks to JMK's link I found out this is basically a wontfix bug popping up in VS debugger under Windows x64. Error fires if application is run outside of debugger.
Its silently erroring.
try
{
if (Properties.Settings.Default["Database"] != null)
{
MessageBox.Show("We landed on spot 1");
}
else
{
MessageBox.Show("We landed on spot 2");
}
}
catch (Exception ee)
{
MessageBox.Show(ee.Message);
}
Comes back with "The settings property 'Database' was not found"
Try adding your project namespace before the Properties
if (WindowsFormsApplication2.Properties.Settings.Default.Database != null)
Propably an exception is thrown and not noticed by the debugger.
This happens for Windows Forms projects on 64bit Windows Versions (and is not a behaviour specific to .NET but to Windows in general).
More details here: Visual Studio does not break at exceptions in Form_Load Event
Try pressing STRG + ALT + E and mark the checkbox "Thrown" for "Common Language Runtime Exceptions".
Now the debugger will break on any exception in Form_Load()
Since I know about that my workaround is to completly avoid using the Load event.
Most of my Forms are Dialogs so I shadow the ShowDialog() method and call a Init() function.
public class Form1
{
public new DialogResult ShowDialog()
{
Init();
return base.ShowDialog();
}
public new DialogResult ShowDialog(IWin32Window owner)
{
Init();
return base.ShowDialog(owner);
}
public void Init()
{
// code goes here
}
}

Basic use of user controls, closing a user control and opening another, user control parameters

ladies and gentlemen, once again I unfortunately am going to bother you with newbie stuff. I have searched for this information for hours, so if there’s a thread with what I want on it, it’s buried deeper than I could find.
This was my first question here, and Mark Hall was kind enough to set me straight. Since then, I have created a new project and recreated my first three screens as user controls – a container/login, a choice screen, and a main screen (currently empty). If a user has more than one collection, the choice screen pops up and allows them to choose a collection.
I did run into a snag with parameters, but I’m solving that by overloading the form declaration (solution found here) – yes, I know it’s much better to send parameters through calls, but I’d hate to have to create a call for each parameter (do I?) and… OK, OK, I’m better at this than {get, set}. Man, I hate being a newbie.
Anyways, I’m having trouble with the choice form – I can’t seem to call it, close it, then go to the main form. I have no problem (if there’s only one collection) in going straight to the main form, it’s that darn choice form. Yes, I know I could include a choice datagridview, but a few of our end users aren’t the sharpest bulb in the tool shed, and need hand-holding. Anyways, here’s the code.
CONTAINER/LOGIN SCREEN
namespace DeleteThis
{
public partial class ContainerForm : Form
{
Main Main = new Main();
LoginCollectionChoice LoginChoice = new LoginCollectionChoice();
DataTable dtPermissions = new DataTable();
public ContainerForm()
{
InitializeComponent();
Main.ExitEvent += new Main.ExitEventHandler(Main_ExitEvent);
LoginChoice.ExitEvent += new
LoginCollectionChoice.ExitEventHandler(LoginChoice_ExitEvent);
}
void LoginChoice_ExitEvent(object sender, EventArgs e)
{
pnlcontainer.Controls.Remove(LoginChoice);
}
void Main_ExitEvent(object sender, EventArgs e)
{
pnlcontainer.Controls.Remove(Main);
}
private void btnLogin_Click(object sender, EventArgs e)
{
LoginProcedure();
}
private void LoginProcedure()
{
DataTable dtPermissions = AdminClass.GetCollectionsForUser(int.Parse(txtbxUserName.Text));
if (dtPermissions.Rows.Count == 1)
{
//Valid user, one collection. Head right in.
pnlcontainer.Controls.Add(Main);
Main.BringToFront();
}
else
{
//More than one collection found. Giving user choice
LoginCollectionChoice LoginChoice = new LoginCollectionChoice(dtPermissions);
pnlcontainer.Controls.Add(LoginChoice);
LoginChoice.BringToFront();
}
}
private void btnExitProgram_Click(object sender, EventArgs e)
{
this.Close();
}
}
}
I hope I didn't kill anything in the snipping. And now the choice screen…
public partial class LoginCollectionChoice : UserControl
{
public delegate void ExitEventHandler(object sender, EventArgs e);
public event ExitEventHandler ExitEvent;
private static DataTable dtPermit;
DataTable dtPermissions = new DataTable();
public LoginCollectionChoice()
{
}
public LoginCollectionChoice(DataTable dtPermissions)
{
InitializeComponent();
GrdCollection.DataSource = dtPermissions;
dtPermit = dtPermissions;
}
private void btnChoose_Click(object sender, EventArgs e)
{
//Code for the user to choose a collection
ExitEvent(this, new EventArgs());
}
}
I’ve snipped all non-relevent code, I hope you gentlemen and ladies can help this newbie get on the right path. Please, be gentle, you wouldn’t want to see me cry, would you? :) Oh! And if you know of any great tutorial sites, please email them to me. I'd prefer to spend a week on tutorials than a week on stumbling and asking here. Thank you all very much.
Are you calling logonForm.Show()?
It seems like you'd need to show it that way.
You use BringToFront(), but I think it needs to be shown first.
The first thing that jumps out to me is that you are calling
LoginCollectionChoice LoginChoice = new LoginCollectionChoice(dtPermissions);
which is creating a local variable called LoginChoice, which is not the same as your class variable even though they share the same name.
What you want to do is to not declare a local variable in that method. Change that line to
LoginChoice = new LoginCollectionChoice(dtPermissions);
Having said that, I believe tylerjgarland in that you need to call .Show() first. And the way you are closing the form is certainly odd. I would create a form, showDialog, get the result and then close the form that way.

Encapsulating a control inside an exception

Relatively new to C#/.NET/GUI programming, but here goes. Right now I'm writing a business application at work using WinForms. I have about 5 textboxes and 1 combobox that I want to verify if is empty and if so then tell the user and set focus on that control. How should I go about doing this?
I could either have an if statement that checks each control:
if (usernameField IsNullOrEmpty) then:
setFocus(UsernameField);
return;
if (addressField IsNullOrEmpty) then:
setFocus(addressField);
return;
continue with rest of application as normal...
Or I could do this with exceptions:
try {
if (usernameField IsNullOrEmpty) then:
throw new Exception(usernameField);
if (addressField IsNullOrEmpty) then:
throw new Exception(addressField);
} catch (Exception e) {
setFocus(ControlField) // encapsulate in exception some way?
}
Or to prevent code duplication, just write a function:
try {
checkField(usernameField);
checkField(addressField);
} catch (Exception e) {
setFocus(ControlField) // encapsulate in exception some way?
}
void checkField(control ctrl) {
if (ctrl IsEmptyOrNull)
throw new Exception(ctrl);
}
Being relatively new to GUI programming, does a text field being empty deserve an exception or would this be considered normal program flow?
Throwing Exceptions for program flow is not recommended.
Write a helper method.
private bool IsTextboxValid(Textbox ctrl)
{
if(string.IsNullOrEmpty(ctrl.Text))
{
ctrl.Focus();
return false;
}
return true;
}
And to use it:
if(!IsTextboxValid(addressBox)) return;
if(!IsTextboxValid(nameBox)) return;
I would not use an exception, exceptions should be thrown in exceptional situations, user not filling in a field doesn't count. As for actually detecting the empty control and setting focus, there are tons of ways, like simple if checks as you have, to more complicated solutions with binding and validation and all that.

dotRAS Disconnected State not triggered

Can someone give me a heads up... I'm trying to use the dotRAS .NET control, and this code to change the value of internetConnected (boolean) using an event handler...
But it seems that the state RasConnectionState.Disconnected is not triggered by dotRAS hangup()..
Any ideas? Am I doing it totally wrong... or have I managed to find a bug?
public class USBModem
{
// private vars
private RasDialer dialer = new RasDialer();
private bool internetConnected = false;
/// <summary>
/// Default constructor for USBModem
/// </summary>
public USBModem()
{
// Add Events for dialer
dialer.StateChanged += new EventHandler<StateChangedEventArgs>(dialer_StateChanged);
}
void dialer_StateChanged(object sender, StateChangedEventArgs e)
{
// Handle state changes here
switch (e.State)
{
case RasConnectionState.Connected:
internetConnected = true;
Console.WriteLine(e.State.ToString());
break;
case RasConnectionState.Disconnected:
internetConnected = false;
Console.WriteLine(e.State.ToString());
break;
default:
Console.WriteLine("INFO -> Unhandled state: " + e.State.ToString());
break;
}
}
public void ConnectInternet(string connectionName)
{
// Dial
dialer.PhoneBookPath = RasPhoneBook.GetPhoneBookPath(RasPhoneBookType.AllUsers);
dialer.EntryName = connectionName;
dialer.DialAsync();
}
public void DisconnectInternet()
{
foreach (RasConnection connection in dialer.GetActiveConnections())
{
connection.HangUp();
}
}
}
I've made some changes to the documentation for RasDialer in the 1.2 release to hopefully address this problem.
Apparently, a very simple (but widespread) mistake.
Basically the RasDialer component only handles events while a dialing operation is in progress.
The disconnected event would be raised if perhaps the modem line became unplugged during the connection attempt.
If you want to monitor client connections on the machine for connection/disconnection or a couple other events, use a RasConnectionWatcher. This will receive notifications from Windows when connection changes are made outside of a dialing operation.
Documentation on dotRAS is particularly sparse on Google... Head to http://dotras.codeplex.com for further information. The Help files included with the SDK are also very useful.

Categories