Windows form loads then quits - c#

I'm creating a checkout system for a supermarket. It consists of a checkout, server and MIS program an operates WCF services between them. The problem I have is that the checkout program, which is a windows form, does a few neccessaries in it's application_load method and then just quits.
Here's the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using CheckoutLibrary;
using Checkout.ServerLibraryService;
using Checkout.MarketService;
namespace Checkout
{
public partial class theForm : Form
{
private static int checkoutID = 3;
private Product[] allProducts;
public theForm()
{
InitializeComponent();
}
private void theForm_Load(object sender, EventArgs e)
{
// First cache all products
SupermarketServiceSoapClient marketService = new SupermarketServiceSoapClient();
allProducts = marketService.GetAllProducts();
// Load the service provided by the server
ServiceClient serverService = new ServiceClient();
// Load the event handlers for the bar code scanner
BarcodeScanner scanner = new BarcodeScanner();
scanner.ItemScanned += new BarcodeScanner.ItemScannedHandler(scanner_ItemScanned);
scanner.AllItemsScanned += new BarcodeScanner.AllItemsScannedHandler(scanner_AllItemsScanned);
scanner.Start(checkoutID);
}
void scanner_AllItemsScanned(EventArgs args)
{
throw new NotImplementedException();
}
void scanner_ItemScanned(ScanEventArgs args)
{
itemTextBox.Text = "Scanned " + GetItemName(args.Barcode);
}
private void scanItemButton_Click(object sender, EventArgs e)
{
scanner_ItemScanned(new ScanEventArgs(GetRandBarcode()));
}
// A barcode -> product name look up method
public string GetItemName(int barcode)
{
return allProducts[barcode].Description + " # " + allProducts[barcode].Price;
}
// Method to grab a random barcode for simulation
private int GetRandBarcode()
{
Random rand = new Random();
return rand.Next(0,500);
}
}
}
And program.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace Checkout
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new theForm());
}
}
}
Thanks for any insight.

In WinForms, if your form_load throws an exception, it quits without displaying anything. Annoying, but I'm guessing that's the problem.
You can try a try/catch, or you can hit CTRL+ALT+E and check the Thrown Column for Common Language Runtime Exceptions to see the error.
UPDATE:
Based on comments, here's a sample way to execute something on another thread.
ThreadStart ts = new ThreadStart(() => {
try {
scanner.Start(checkoutID);
} catch {
// Log error
}
});
Thread t = new Thread(ts);
t.Start();

Related

The calling thread cannot access this object because a different thread owns it (in v4.5)

I am aware that there are plenty questions have been already asked on this. But the solutions provided about delegates is not what I am getting to work with my code because I am working on 4.5 version and looks like the Dispatcher methods have slightly changed. Added to that, I am touching dotnet nearly after a decade and c# for the first time.
What I am actually tying to do in my WPF project is to append text of the textbox inside the main window to display the status/log. This is inside the singleton class called Logger The main static function of this class is log() which accepts a string which needs to be added to the text box with one simple line
txt.AppendText(msg);
After doing some research I changed it to
Dispatcher.CurrentDispatcher.Invoke(() =>
{
txt.AppendText(msg);
});
But I still get the same error. What is going wrong here? Is there anything else to do? Because I am calling this Logger.log() from FileSystemEventHandler insider another singleton class.
private void somethingChanged(object sender, FileSystemEventArgs e)
{
Logger.log("File: " + e.FullPath + " " + e.ChangeType);
}
Below is my Logger class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Threading;
namespace httpclientui.comps
{
class Logger
{
private static TextBox txt;
private Logger() { }
public static void setup(TextBox t){
txt = t;
}
public static void clear()
{
if (txt == null)
{
return;
}
txt.Clear();
}
public static void log(String msg, bool addNewLineChar = true)
{
if (txt == null)
{
return;
}
Dispatcher.CurrentDispatcher.Invoke(() => {
txt.AppendText(msg);
});
}
}
}
This is my main window with only one textbox control called txtMessage.
public partial class MainWindow : Window
{
private String folderToWatch;
public MainWindow()
{
InitializeComponent();
initialize();
}
private void initialize()
{
Logger.setup(txtMessage);
Logger.clear();
Logger.log("Launched");
folderToWatch = "E:\\folder\\subfolder";
Watcher.Instance.setup(folderToWatch);
Watcher.Instance.start();
}
}
}
Below is my Watcher class which has FileSystemWatcher object to keep watching one of the folder and whenever something happens inside that folder like adding/deleting files and renaming the files will needs to be logged inside that textbox.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
namespace httpclientui.comps
{
class Watcher
{
private String path;
//https://msdn.microsoft.com/en-us/library/system.io.filesystemwatcher(v=vs.110).aspx
private FileSystemWatcher dog;
private static Watcher instance;
private Watcher()
{
//dog = new FileSystemWatcher()
}
public static Watcher Instance
{
get
{
if (instance == null)
{
instance = new Watcher();
}
return instance;
}
}
public void setup(String folderPath)
{
path = folderPath;
dog = new FileSystemWatcher(folderPath);
Logger.log("setting up to watch folder: " + folderPath);
dog.Changed += new FileSystemEventHandler(somethingChanged);
dog.Created += new FileSystemEventHandler(somethingChanged);
dog.Deleted += new FileSystemEventHandler(somethingChanged);
dog.Renamed += new RenamedEventHandler(somethingRenamed);
}
public void start()
{
Logger.log("starting to watch folder");
dog.EnableRaisingEvents = true;
}
public void pause()
{
dog.EnableRaisingEvents = false;
}
public void stop()
{
dog.EnableRaisingEvents = false;
}
private void somethingChanged(object sender, FileSystemEventArgs e)
{
Logger.log("File: " + e.FullPath + " " + e.ChangeType);
}
private void somethingRenamed(object sender, RenamedEventArgs e)
{
Logger.log("File: " + e.OldFullPath + " renamed to " + e.FullPath);
}
}
}
At first glance, it looks like you are not marshalling the Clear() method call to the Dispatcher. That's what is likely throwing the exception- all access to DispatcherObjects (which includes all Controls) must be done by the Dispatcher thread.
Also, you want to use Application.Current.Dispatcher, not Dispatcher.CurrentDispatcher. The latter just spins up a new Dispatcher on the current (background) thread, which is not what you want.

C# speech recogntion engine recognizes everything wrong

I have been trying to make a personal assistant in my free time, and so far i have made him speak, but now i am trying to speak to him. Whenever i do however, he fails massively. When i say "Hello my name is Alexander" he recognizes "in the name is unresolved bush" or something else that is just not correct. am i doing something wrong or is the built in C# recognition engine just broken?
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Speech.Recognition;
using System.Speech.Synthesis;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TTS_Test
{
class Jarvis
{
private static SpeechSynthesizer synthezier;
private static String name;
public Jarvis()
{
synthezier = new SpeechSynthesizer();
synthezier.SelectVoiceByHints(VoiceGender.Male, VoiceAge.Senior);
synthezier.Volume = 100;
synthezier.Rate = 0;
}
private bool isFirstTime()
{
if (File.Exists("config"))
{
return false;
}else{
return true;
}
}
private void firstTimeSetup()
{
say("Hello, My name is Jarvis. It seems that this is your first time here. Please take some time to configure the application.");
Config config = new Config();
config.ShowDialog();
say("Thank you! I should be up and running now.");
}
public void initiate()
{
if (isFirstTime())
{
firstTimeSetup();
}
setupUserData();
say("Hello " + name+". How may i help you today?");
recognize();
}
public void setupUserData()
{
StreamReader reader = new StreamReader("config");
name = reader.ReadLine();
reader.Close();
}
public void say(string output)
{
synthezier.Speak(output);
}
public void recognize()
{
SpeechRecognitionEngine sr = new SpeechRecognitionEngine(new System.Globalization.CultureInfo("en-GB"));
sr.LoadGrammar(new DictationGrammar());
sr.InitialSilenceTimeout = TimeSpan.FromSeconds(5);
sr.SetInputToDefaultAudioDevice();
RecognitionResult result = sr.Recognize();
MessageBox.Show(result.Text);
}
}
}
You should train your computer to better understand you by going to the Control Panel\All Control Panel Items\Speech Recognition

wiimotelib bug?

I am recently writing a wiimote program:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using WiimoteLib;
namespace WiiTester
{
public partial class Form1 : Form
{
Wiimote wm = new Wiimote();
public Form1()
{
InitializeComponent();
wm.WiimoteChanged += wm_WiimoteChanged;
wm.WiimoteExtensionChanged += wm_WiimoteExtensionChanged;
wm.Connect();
wm.SetReportType(InputReport.IRAccel, true);
}
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
void wm_WiimoteExtensionChanged(object sender, WiimoteExtensionChangedEventArgs args)
{
if (args.Inserted)
{
wm.SetReportType(InputReport.IRExtensionAccel, true);
}
else
{
wm.SetReportType(InputReport.IRAccel, true);
}
}
}
}
My wiimote keeps getting disconnected and this error keeps running on wm.Connect();
Timed out waiting for status report
Is there a solution?
I have a lot of experience with this library, and your problem is most likely being caused because you are calling SetRumble so often, this code:
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
if (ws.ButtonState.A == true)
{
wm.SetRumble(true);
}
else
{
wm.SetRumble(false);
}
}
Will call SetRumble constantly whether A is down or not, consider using this code instead:
bool rumbleOn = false;
void wm_WiimoteChanged(object sender, WiimoteChangedEventArgs args)
{
WiimoteState ws = args.WiimoteState;
bool newRumble = (ws.ButtonState.A == true);
if (rumbleOn != newRumble)
{
rumbleOn = newRumble;
wm.SetRumble(rumbleOn);
}
}
This way the set rumble method is only called when required and not constantly sending output reports to the WiiMote which causes the Bluetooth BUS to overload.

Does WqlEventQuery contain a constructor with 1 argument?

I am trying to create a simple service in C# using VS2008 that creates a text file when the computer goes into sleep mode. My current code throws out the following error:
'SleepNotifierService.WqlEventQuery' does not contain a constructor that takes '1' arguments
Now I looked in the Object browser, and it looks like it does take in one argument. This is what the browser had to say:
public WqlEventQuery(string queryOrEventClassName)
Here is my code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Management;
using System.IO;
namespace SleepNotifierService
{
public class WqlEventQuery : EventQuery { }
public partial class Service1 : ServiceBase
{
ManagementEventWatcher _watcher;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("Win32_PowerManagementEvent");
_watcher = new ManagementEventWatcher(query);
_watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
_watcher.Start();
}
protected override void OnStop()
{
_watcher.Stop();
}
void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
try
{
int eventType = Convert.ToInt32(e.NewEvent.Properties["EventType"].Value);
switch (eventType)
{
case 4:
Sleep();
break;
case 7:
Resume();
break;
}
}
catch (Exception ex)
{
//Log(ex.Message);
}
}
public void Sleep()
{
StreamWriter SW;
SW = File.CreateText("c:\\MyTextFile.txt");
SW.WriteLine("Sleep mode initiated");
SW.Close();
}
public void Resume()
{
}
}
}
Am I interpreting that object browser wrong? I'm new to creating services and C#/.NET in general so it might be something trivial.
Appreciate any help,
Tomek
You're using wrong WqlEventQuery. There's one defined in System.Management and it indeed has a one-argument constructor, but there's also your custom WqlEventQuery class.
If you want to use .NET BCL's class, you'll have to fully qualify it:
var query = new System.Management.WqlEventQuery("Win32_PowerManagementEvent");
or even prefix it with global keyword:
var query = new global::System.Management.WqlEventQuery("Win32_PowerManagementEvent");

How can I call this webservice asynchronously?

In Visual Studio I created a web service (and checked "generate asynchronous operations") on this URL:
http://www.webservicex.com/globalweather.asmx
and can get the data out synchronously but what is the syntax for getting the data out asychronously?
using System.Windows;
using TestConsume2343.ServiceReference1;
using System;
using System.Net;
namespace TestConsume2343
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
GlobalWeatherSoapClient client = new GlobalWeatherSoapClient();
//synchronous
string getWeatherResult = client.GetWeather("Berlin", "Germany");
Console.WriteLine("Get Weather Result: " + getWeatherResult); //works
//asynchronous
client.BeginGetWeather("Berlin", "Germany", new AsyncCallback(GotWeather), null);
}
void GotWeather(IAsyncResult result)
{
//Console.WriteLine("Get Weather Result: " + result.???);
}
}
}
Answer:
Thanks TLiebe, with your EndGetWeather suggestion I was able to get it to work like this:
using System.Windows;
using TestConsume2343.ServiceReference1;
using System;
namespace TestConsume2343
{
public partial class Window1 : Window
{
GlobalWeatherSoapClient client = new GlobalWeatherSoapClient();
public Window1()
{
InitializeComponent();
client.BeginGetWeather("Berlin", "Germany", new AsyncCallback(GotWeather), null);
}
void GotWeather(IAsyncResult result)
{
Console.WriteLine("Get Weather Result: " + client.EndGetWeather(result).ToString());
}
}
}
I suggest using the event provided by the auto-generated proxy instead of messing with the AsyncCallback
public void DoWork()
{
GlobalWeatherSoapClient client = new GlobalWeatherSoapClient();
client.GetWeatherCompleted += new EventHandler<WeatherCompletedEventArgs>(client_GetWeatherCompleted);
client.GetWeatherAsync("Berlin", "Germany");
}
void client_GetWeatherCompleted(object sender, WeatherCompletedEventArgs e)
{
Console.WriteLine("Get Weather Result: " + e.Result);
}
In your GotWeather() method you need to call the EndGetWeather() method. Have a look at some of the sample code at MSDN. You need to use the IAsyncResult object to get your delegate method so that you can call the EndGetWeather() method.

Categories

Resources