NullReferenceException when trying to send bytes via Bluetooth in C# - c#

This is first time I am doing with Bluetooth connection in C#. I am trying to send byte (data type) from application written in C# over Bluetooth.
This is my code:
public class ConnectionManager
{
private StreamSocket socket;
private DataWriter dataWriter;
public void Initialize()
{
socket = new StreamSocket();
}
public void Terminate()
{
if (socket != null)
{
socket.Dispose();
}
}
public async void connect(HostName hostName)
{
if (socket != null)
{
await socket.ConnectAsync(hostName, "1");
dataWriter = new DataWriter(socket.OutputStream);
}
}
//sending data via Bluetooth
public void sendCommand(byte command)
{
dataWriter.WriteByte(command);
}
}
private ConnectionManager connectionManager;
// Constructor
public MainPage()
{
InitializeComponent();
connectionManager = new ConnectionManager();
}
private async void AppToDevice()
{
PeerFinder.AlternateIdentities["Bluetooth:Paired"] = "";
var pairedDevices = await PeerFinder.FindAllPeersAsync();
if (pairedDevices.Count == 0)
{
Debug.WriteLine("No devices found.");
}
else
{
foreach (var pairedDevice in pairedDevices)
{
if (pairedDevice.DisplayName == "HC-06")
{
connectionManager.connect(pairedDevice.HostName);
continue;
}
}
}
}
private void send_Click(object sender, RoutedEventArgs e)
{
byte command = Convert.ToByte(commandTextBox.Text);
connectionManager.sendCommand(command);
}
private void connect_Click(object sender, RoutedEventArgs e)
{
AppToDevice();
}
When I enter some value (for example 1 or 2) in commandTextBox and tap on Send button application crashes. This is the error message: An exception of type 'System.NullReferenceException' occurred in TestBluetooth.DLL but was not handled in user code
Can someone help me?

Sounds like a very basic error. Some object is null. It will happen when you try to access a method or a property on an object that is null.
Troubleshooting:
Check the stacktrace of the error. It says where it fails.
Turn on break on all exceptions when you debug so you can see where exactly it fails, and see which object is null.
If you can not debug it, add a try/catch around all the code in every method you have and use a MessageBox.Show(ex.ToString()) to display the full error with stacktrace when it fails.
If the error occurs in a third party dll, make sure to turn off Debugging->"Enable Just My Code" in Options in Visual Studio.
Download and install Red Gate's Reflector if it fails outside your code and you dont have the source for it. Reflector will "extract" out the code of the DLL and show you exactly the line it fails (or so I believe it does).
When you get an error saying "was not handled in user code" it means an Exception was thrown and not handled by a try/catch by you. I have a finger on the async method you have there.
If I ever play around with threads, i ALWAYS have a try/catch around all my code within the threaded code. I recommend adding a try/catch in the AppToDevice() method. Also add it for all your Form events. Show a message of error to the user or handle it and hide the error from the user.
Check these:
Best Practice for Exception Handling in a Windows Forms Application?
Exception handling in threads

Related

VS2017 doesn't give details for an exception, just crashed with null

I'm working on a UWP project and there's something funky going on with how errors are being presented to me. I don't know if it's VS2017 or how UWP is set up.
I have a piece of code that goes online and retrieves json content, sometimes the code works and sometimes it doesn't. It works when I use Expander control from UWP Community toolkit, and fails when I want to switch to GridView. When it doesn't work, it fails on GetStringAsync method of HttpClient. The strange behavior is that the exception isn't thrown in the method where the problem occurs, the code actually redirects me back without giving an error and as soon as it gets to the property that's supposed to have a value that isn't null, I get a null exception.
This is where the problem happens:
string httpContent = "";
using (HttpClient httpClient = new HttpClient())
{
try
{
httpContent = await httpClient.GetStringAsync(uri);
}
catch (Exception e)
{
// TODO: handle errors
var x = "";
}
}
This piece of code is called from within the view model. It starts with a constructor and RefreshServerKanesWrathDataAsync is the method where json is parsed.
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
cnconline.RefreshServerKanesWrathDataAsync();
}
The second I get to GetStringAsync, the code just goes back to the constructor like nothing happened, however the method never completes, it just exits back to the constructor, and therefore fails to update observable collections with data. I then get a null exception.
I wanted to test this with VS2015, but I updated some controls that are apparently only supported withing VS2017, so I can't run the code in other versions.
I also ran into an issue with the code prior to this problem, where I tried to access files in a directory without using a token. The behavior was exactly the same, the code wasn't telling me that I didn't have access to the directory I wanted to read, it was just throwing me out of the method back into the location that made the call to read the directory. Just like with the current problem, I would then run into a null exception, which wasn't where the main problem was.
I added Template10 and UWP community toolkit to the project, if that matters.
You shouldn't call an async method from a constructor unless you're willing to provide a callback.
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task<string>
t.ContinueWith(OnCompleted);
}
private void OnCompleted(Task<string> task)
{
if (task.IsFaulted)
{
// Check error
var exception = task.Exception;
}
else if (task.IsCanceled)
{
// User hit cancel?
}
else
{
// All good!
var result = task.Result;
}
}
Here's a sample where RefreshServerKanesWrathDataAsync() returns just Task (not Task<result>)
public CncOnlinePageViewModel()
{
cnconline = new CncOnline();
var t = cnconline.RefreshServerKanesWrathDataAsync(); // assuming returns Task
t.ContinueWith(OnCompleted);
}
private void OnCompleted(Task task)
{
if (task.IsFaulted)
{
// Check error
var exception = task.Exception;
}
else if (task.IsCanceled)
{
// User hit cancel?
}
else
{
// All good!
}
}
On a side note, you may also need to have Visual Studio 2017 break when any exception is thrown. In VS2017, go to Debug->Windows->Exception Settings and make sure Common Language Runtime Exceptions has a check. If it has a filled box, click the box until it turns into a checkmark.
Also..., you can tap into an event raised when any task has an unobserved exception. You can do so in the constructor of App.xaml.cs
public App()
{
TaskScheduler.UnobservedTaskException += OnUnobservedException;
}
private static void OnUnobservedException(object sender, UnobservedTaskExceptionEventArgs e)
{
// Put break point here.
var ex = e.Exception;
// This will keep your app alive, but only do it if it's safe to continue.
e.SetObserved();
}

Calling web service asynchronously (C#) - completed event breakpoint not hit

Can't get to the bottom of this one and it's obviously something daft, could anyone help please?
I'm calling a web service asynchronously using a C# console application, and a breakpoint in the 'completed' event is never getting hit.
Here's the example code, really simple:
public static void CallWebservice()
{
try
{
ServiceReference1.GlobalWeatherSoapClient proxy = new GlobalWeatherSoapClient();
proxy.GetCitiesByCountryCompleted += proxy_GetCitiesByCountryCompleted;
proxy.GetCitiesByCountryAsync("France");
}
catch (FaultException faultException)
{
var error = faultException.Message;
}
}
static void proxy_GetCitiesByCountryCompleted(object sender, GetCitiesByCountryCompletedEventArgs e)
{
//Do something here
throw new NotImplementedException();
}
So the breakpoint on the line
throw new NotImplementedException();
is never hit.
However if I add an additional line after the actual asynch call:
System.Threading.Thread.Sleep(5000);
..the breakpoint is now getting hit OK. Can anyone explain what's going on here? Obviously something to do with threads and the debugger, but I don't understand what?
This is because proxy is going out of scope and so being cleaned up (therefore losing your callback).
So, you need to move your Proxy OUT of the call so that its lifetime is controlled by you:
private ServiceReference1.GlobalWeatherSoapClient _proxy;
public void CallWebservice()
{
try
{
_proxy = new GlobalWeatherSoapClient();
_proxy.GetCitiesByCountryCompleted += proxy_GetCitiesByCountryCompleted;
_proxy.GetCitiesByCountryAsync("France");
}
catch (FaultException faultException)
{
var error = faultException.Message;
}
}
public void proxy_GetCitiesByCountryCompleted(object sender, GetCitiesByCountryCompletedEventArgs e)
{
//Do something here
throw new NotImplementedException();
}
This is not a perfect example as without seeing rest of your code I can't tell you where to instantiate proxy. Not in CallWebservice but in a constructor etc but hopefully you get the idea!
You should await on the call to proxy.GetCitiesByCountryAsync("France"), otherwise you'll come out of the try block before the function completes.

Windows service starts and then stops, can't figure out the bug [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am trying to read a file at constant intervals and then send the data queried to a specific webserver. The following is the code I am using, but the service starts and stops without doing any thing. I can't Figure out the bug.
public partial class IPTProjectService : ServiceBase
{
private Thread checkingThread;
private System.Timers.Timer timer;
Boolean sendingTime;
public IPTProjectService()
{
InitializeComponent();
checkingThread = new Thread(update);
timer = new System.Timers.Timer(Properties.Settings.Default.TIMEINTERVAL);
timer.Elapsed += timer_Elapsed;
sendingTime = true;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
setSendingTime();
if (!File.Exists("Testfile.txt"))
{
File.Create("Testfile.txt");
timer_Elapsed(sender, e);
}
else
{
File.WriteAllText("Testfile.txt", timer.ToString());
}
}
private void setSendingTime()
{
sendingTime = true;
}
private void update()
{
while (true)
{
if (sendingTime)
{
CarpoolWebClient.sendData(Properties.Settings.Default.DATAFILE);
sendingTime = false;
}
}
}
protected override void OnStart(string[] args)
{
try
{
timer.Start();
checkingThread.Start();
}
catch (Exception ex)
{
Debug.Fail(ex.ToString());
}
}
protected override void OnStop()
{
try
{
timer.Stop();
checkingThread.Abort();
}
catch(Exception e)
{
StreamWriter writer = new StreamWriter("testfile.txt", true);
writer.Write(e.ToString());
writer.Close();
}
}
}
class CarpoolWebClient
{
public static void sendData(String fileName)
{
WebRequest req = null;
WebResponse rsp = null;
try
{
//URL of message broker
string uri = "http://localhost/IPTProject/receive_xml.php";
req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "text/xml";
// Wrap the request stream with a text-based writer
StreamWriter writer = new StreamWriter(req.GetRequestStream());
// Write the xml text into the stream
writer.WriteLine(GetTextFromXMLFile(#fileName));
writer.Close();
rsp = req.GetResponse();
}
catch (WebException webEx)
{
//MessageBox.Show(webEx.Message);
throw webEx;
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
throw ex;
}
finally
{
if (req != null) req.GetRequestStream().Close();
if (rsp != null) rsp.GetResponseStream().Close();
}
}
private static string GetTextFromXMLFile(string file)
{
StreamReader reader = new StreamReader(file);
string ret = reader.ReadToEnd();
reader.Close();
return ret;
}
}
If you can, debug the service. If it's a problem because the service is set to automatically start then you can use this "trick" to automatically attach the debugger and figure out what is going wrong that way.
The call to
File.Create("Testfile.txt");
timer_Elapsed(sender, e);
will create a file and return a FileStream to the newly created file. This file is subsequently still open then timer_Elapsed is called and will cause the application to fail as it cannot open the file a second time. See the MSDN Docs on the subject.
The Create call is not required for your code, you can simplyfying the method to the example below, and it should resolve this issue. Alternatively, close the FileStream object.
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
setSendingTime();
File.WriteAllText("Testfile.txt", timer.ToString());
}
File.WriteAllText will create the file is it does not exist, and overwrite the file if it does exist, effectively doing the same thing as your check.
If this does not resolve the issue, check the event log for errors, or alternatively provided error handling code in your timer_Elapsed and update methods that log the error message.
As I was requesting the webserver on my own computer i.e. localhost, I didn't noticed that wampserver was not running. I checked the event log which showed me the WebException. Starting the wampserver code works fine. Thank you every one.
Yes, I encountered similar issues a lot of times...
Log all uncaught exceptions:
// Somewhere at the start of the constructor:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
[...]
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// Log exeption e.ExceptionObject.ToString to a file
}
Also, I would use a try-catch + log in the update method to make sure that if the thread exits for any unknown reason, you find out the reason.
If these things don't work, it's usually something stupid like a missing DLL, the incorrect version of a DLL (64/32-bit mix), or something like that. This can be found in the event log.
That should do it :-)
If you are running this on a machine that has Visual Studio installed (e.g., your dev machine), add a call to
System.Diagnostics.Debugger.Launch();
in your startup or wherever appropriate. This will launch the Visual Studio debugger, so you don't have to fight with timing issues (Service stopping before you can manually attach the debugger)

How to wait for an Autoreset event to occur before taking any other action?

This is about the AutoResetEvent in C#. I tried to read other answers but I could not make sense and apply to my scenario. I am not writing any threading application. Just a small application to read/validate a file and update.
So I have this requirement to write some code for reading a fixed length file, validating it and then if it is valid upload it to Database.
I got everything working until I got stuck with the AutoResetEvent. So here is what is happening. Once the data is parsed/read I validate it using Flat File Checker utility in C#. So I called the functions into my application. Here is the snippet.
private AutoResetEvent do_checks = new AutoResetEvent(false);
public bool ValidationComplete = false;
This part goes in initialization code:
this._files.Validated += new EventHandler<SchemaValidatedEventArgs>(FileSetValidated);
public bool ValidateFile()
{
try
{
RunValidation();
return true;
}
catch (Exception e)
{
log.Error("Data Validation failed because :" + e.Message);
return false;
}
}
private void RunValidation()
{
// Use Flat File Checker user interface to create Schema file.
do_checks = _files.RunChecks();
log.Debug("Validation Started");
}
This is the method that is getting called asnchronusly during the validation process:
public void FileSetValidated(Object sender, SchemaValidatedEventArgs e)
{
try
{
ValidationComplete = e.Result;
if (IsDataValid)
{
log.Debug("Data is validated and found to be valid.");
}
else
{
log.Debug("Data is validated and found to be Invalid");
}
}
finally
{
do_checks.Set();
}
}
What is happening is that even before I get any value set into ValidationComplete the code is checked for Validation complete and because it is set by default to false, it returns false. The code in the FileSetValidated gets executed after that so the database update never happens.
The reason is that I cannot change the code because the Flat File Checker only accepts an AutoResetEvent as a return variable in RunChecks method.
******Here is what I did now*******
private AutoResetEvent do_checks;
public bool ValidateFile()
{
try
{
string extFilePath = surveyFile.ExtFilePath;
File.Copy(extFilePath, localTempFolder + "ExtractFile.Dat");
RunValidation();
if (!do_checks.WaitOne(TimeSpan.FromSeconds(30))) {
// throw new ApplicationException("Validation took more than expected!");
}
return true;
}
catch (Exception e)
{
log.Error("Data Validation failed because :" + e.Message);
return false;
}
}
private void RunValidation()
{
// Use Flat File Checker user interface to create Schema file.
do_checks = _files.RunChecks();
do_checks.WaitOne();
log.Debug("Validation Started");
}
Also I moved the part where data about validation gets passed on towards the beginning of the event handler so atleast that part gets executed. This helped but I am not sure if it is correct.
I have never worked with that lib, so I just downloaded it and looked into the code.
First of all, as "500 - Internal Server Error" already mentioned, it seems that part of the code is missing, at least "try" in the FileSetValidated method. I don't see any place where you are waiting for the event via WaitOne.
You don't need to create do_checks by yourself, because _files.RunChecks() creates AutoResetEven for this particular file's processing. So if you are using the same field for that event - you will get issue if you will need to process few files at the same time. So keep separate event for each file, in any case I don't see reason to keep that references as members if you don't want to stop processing in the middle (if you will call do_checks.Set() during processing, it will cancel processing without finishing it).
As I see in the lib code, you should not call do_checks.Set() in the FileSetValidated method, because it will be set, once processing will be done, so you can just write:
var do_checks = _files.RunChecks();
do_checks.WaitOne();
Feel free to share if that helped.
UPDATE:
I am not able to check that lib now to undestand why do_checks is set after starting processing, but I can suggest you to use your initial code with next RunValidation method:
private void RunValidation()
{
do_checks.Reset(); //reset state
_files.RunChecks(); //don't store event from the lib
log.Debug("Validation Started");
do_checks.WaitOne(); //Wait for FileSetValidated to set this event
}
Before exiting the ValidateFile function you need to wait for the validation to complete (wait on the AutoResetEvent) and return the validation result.
Try something like this:
public bool ValidateFile()
{
//try
{
RunValidation();
//Allocate enough time for the validation to occur but make sure
// the application doesn't block if the _files.Validated event doesn't get fired
if(!do_checks.WaitOne(TimeSpan.FromSeconds(10)))
{
throw ApplicationException("Validation took more than expected!");
}
return ValidationComplete;
}
//I would not catch the exception since having an error doesn't mean that the file
//is invalid. Catch it upper in the call stack and inform the user that the validation
//could not be performed because of the error
//catch (Exception e)
//{
// log.Error("Data Validation failed because :" + e.Message);
// return false;
//}
}

To handle exception with every form or just at main

I have a question about handling exception. I have a Winform that uses a webservice proxy on each form for data retrieval and processing. Here is where I really got confused and having a long time deciding which is better.
A. For each call in the web service do a try catch to display the error message and allow the user to re try the process by clicking the button again.
B. Since the error occurred on the web-service and the error was probably because the web service was inaccessible, just make a generic try catch in the WinMain function in the Program.cs and show an error message that web service is inaccessible before the application closes.
The main argument in this is A is more user friendly but needs a lot of try catch code. B is easier to code but just lets the application ends. I am leaning on A but am trying to search the net with options how to lessen the code needed to be written to do this. Any ideas there?
When you add a web reference, the code generator automatically adds "Async" methods to access the web service.
I would recommend that you use the Async methods rather than the synchronous methods. The nice thing about that is that the EventArgs for the Async methods provide an Error property that you can use to see if the request was successful or not.
private void CheckWebservice(string data)
{
WebService.Server server = new WebService.server();
server.methodCompleted += server_methodCompleted;
server.methodAsync(data);
}
private void server_methodCompleted(object sender, methodCompletedEventArgs e)
{
if (e.Error != null)
if (MessageBox.Show("Error", "Error", MessageBoxButtons.AbortRetryIgore) == DialogResult.Retry)
{
// call method to retry
}
else
{
if (e.Result == "OK") { // Great! }
}
}
If you must use the synchronous methods for some reason, then you could, of course, write a class to encapsulate the methods to call your web service so that you can call it from various places without duplicating the code. Your encapsulation class could do all the error handling and return a result.
class CallWebService
{
public enum Result
{ Unknown, Success, NotAvailable, InvalidData } // etc
public Call(string data)
{
Webservice.Server server = new Webservice.Server();
string result = string.Empty;
try
{
result = server.getResult(data);
}
catch (Exception ex) // replace with appropriate exception class
{
return Result.NotAvailable;
}
if (result == "OK") return Result.Success
else return Result.InvalidData;
}
}
Encapsulate the webservice call and the try/catch block inside a class =)

Categories

Resources