Listener hangs when trying to remove - c#

I have a button connected to the start and stop below. After a number of button clicks the application hangs on Trace.Listeners.Remove(_listener). Any idea why?
public void StartListener(ITraceTextSink sink)
{
if (_listener != null) return;
_listener = new TraceSource(sink);
Trace.AutoFlush = true;
Trace.Listeners.Add(_listener);
}
public void StopListener()
{
if (_listener == null) return;
Trace.Listeners.Remove(_listener);
_listener.Dispose();
_listener = null;
}

Related

Socket.ReceiveAsync not calling e.Completed event

I'm changing some old sync/threaded code to async,
basically im implementing a 'server emulator' for an old flash game,
and trying to make the packet reading async to hopefully speed things up a little.
private List<byte> currentPacket = new List<byte>();
private byte[] workBuffer = new byte[1028];
private bool dcLock = false;
public GameClient(Socket clientSocket)
{
ClientSocket = clientSocket;
RemoteIp = clientSocket.RemoteEndPoint.ToString();
if (RemoteIp.Contains(":"))
RemoteIp = RemoteIp.Substring(0, RemoteIp.IndexOf(":"));
Logger.DebugPrint("Client connected # " + RemoteIp);
kickTimer = new Timer(new TimerCallback(kickTimerTick), null, kickInterval, kickInterval);
warnTimer = new Timer(new TimerCallback(warnTimerTick), null, warnInterval, warnInterval);
minuteTimer = new Timer(new TimerCallback(minuteTimerTick), null, oneMinute, oneMinute);
connectedClients.Add(this);
SocketAsyncEventArgs e = new SocketAsyncEventArgs();
e.Completed += receivePackets;
e.SetBuffer(workBuffer, 0, workBuffer.Length);
ClientSocket.ReceiveAsync(e);
}
public static void CreateClient(object sender, SocketAsyncEventArgs e)
{
Socket eSocket = e.AcceptSocket;
e.AcceptSocket = null;
socket.AcceptAsync(e);
GameClient client = new GameClient(eSocket);
}
private void receivePackets(object sender, SocketAsyncEventArgs e)
{
// HI1 Packets are terminates by 0x00 so we have to read until we receive that terminator
if (e.SocketError == SocketError.Success && !isDisconnecting)
{
int availble = e.BytesTransferred;
if (availble >= 1)
{
for (int i = 0; i < availble; i++)
{
currentPacket.Add(e.Buffer[i]);
if (e.Buffer[i] == PacketBuilder.PACKET_TERMINATOR)
{
parsePackets(currentPacket.ToArray());
currentPacket.Clear();
}
}
}
Array.Clear(e.Buffer);
ClientSocket.ReceiveAsync(e);
return;
}
else
{
Disconnect();
}
while (dcLock) { }; // Refuse to shut down until dcLock is cleared. (prevents TOCTOU issues.)
// Stop Timers
if (inactivityTimer != null)
inactivityTimer.Dispose();
if (warnTimer != null)
warnTimer.Dispose();
if (kickTimer != null)
kickTimer.Dispose();
// Call OnDisconnect
connectedClients.Remove(this);
GameServer.OnDisconnect(this);
LoggedIn = false;
// Close Socket
ClientSocket.Close();
ClientSocket.Dispose();
return;
}
now you see
e.Completed += receivePackets;
e.SetBuffer(workBuffer, 0, workBuffer.Length);
ClientSocket.ReceiveAsync(e);
for some reason receivePackets is never being called,
if i open up NetCat and connect to 127.0.0.1:12321 and send stuff there it works,
but from in the original flash-based client of the game? nothing happens.
no call to receivePackets ever happens, even if the buffer is only 1 byte.
even after disconnecting the client...
but it worked in my sync implementation where i just called clientSocket.Receive() in a loop.. so why doesnt it work now in async verison?

What is the best place to declare the connection of my socket and my spot in the background?

I develop an HMI under the UWP, it needs a connection to a server and a background task to monitor whether messages are received.
At the launch of the HMI, an extended splash screen is appearing with a progress ring. To unblock the startup, you have to receive "launch_ok " from the server then we have access to the main page which allows to manage calls.
Currently I declare everything in my file: ExtendedSplash.xaml.cs
I declare my new socket with these settings, I run it and then I run my background activity.
I have also some errors : "Exception levée : 'System.NullReferenceException'"
ExtendedSplash.xaml.cs (Extract):
namespace PhoneCenter
{
partial class ExtendedSplash : Page
{
// SOCKET CONFIGURATION
private const string socketId = "SampleSocket";
private StreamSocket socket = null;
private IBackgroundTaskRegistration task = null;
private const string port = "40404";
private const string adress = "172.16.161.80";
}
public ExtendedSplash(SplashScreen splashscreen, bool loadState)
{
InitializeComponent();
Window.Current.SizeChanged += new WindowSizeChangedEventHandler(ExtendedSplash_OnResize);
splash = splashscreen;
Debug.WriteLine("Création de la tâche d'arrière plan");
StartBackgroundTask();
Debug.WriteLine("Connexion Socket ...");
StartConnexionServeurLTO();
if (splash != null)
{
splash.Dismissed += new TypedEventHandler<SplashScreen, object>(DismissedEventHandler);
splashImageRect = splash.ImageLocation;
PositionImage();
PositionRing();
PositionTextBlock();
}
rootFrame = new Frame();
RestoreState(loadState);
}
// CONNEXION SOCKET
private async void StartConnexionServeurLTO()
{
ApplicationData.Current.LocalSettings.Values["hostname"] = adress;
ApplicationData.Current.LocalSettings.Values["port"] = port;
try
{
SocketActivityInformation socketInformation;
if (!SocketActivityInformation.AllSockets.TryGetValue(socketId, out socketInformation))
{
Debug.WriteLine("Boucle");
socket = new StreamSocket();
socket.EnableTransferOwnership(task.TaskId, SocketActivityConnectedStandbyAction.Wake);
var targetServer = new HostName(adress);
await socket.ConnectAsync(targetServer, port);
DataReader reader = new DataReader(socket.InputStream);
reader.InputStreamOptions = InputStreamOptions.Partial;
var read = reader.LoadAsync(250);
read.Completed += (info, status) =>
{
};
await socket.CancelIOAsync();
socket.TransferOwnership(socketId);
socket = null;
}
}
catch
{
Debug.WriteLine("Echec dans la connexion au serveur");
}
}
// LANCEMENT TÂCHE EN ARRIERE PLAN
private void StartBackgroundTask()
{
try
{
foreach (var current in BackgroundTaskRegistration.AllTasks)
{
if (current.Value.Name == "PhonieMarthaBackground")
{
task = current.Value;
break;
}
}
if (task == null)
{
var socketTaskBuilder = new BackgroundTaskBuilder();
socketTaskBuilder.Name = "PhonieMarthaBackground";
socketTaskBuilder.TaskEntryPoint = "PhonieMarthaBackground.SocketActivityTask";
var trigger = new SocketActivityTrigger();
socketTaskBuilder.SetTrigger(trigger);
task = socketTaskBuilder.Register();
}
SocketActivityInformation socketInformation;
if (SocketActivityInformation.AllSockets.TryGetValue(socketId, out socketInformation))
{
socket = socketInformation.StreamSocket;
socket.TransferOwnership(socketId);
socket = null;
}
Debug.WriteLine("Tâche d'arrière plan démarrée");
}
catch (Exception exception)
{
Debug.WriteLine(exception.Message);
}
}
}
Wouldn't it be simpler to perform these actions in the App.xaml.cs file when launching OnLaunched? Could we call a function at the end of OnLaunched?
The issue you are facing is that in the if you are checking whether the value was not found:
if (!SocketActivityInformation.AllSockets.TryGetValue(socketId, out socketInformation))
{
// Your code
}
If this value is false, then a value for socketId was not found, therefore socketInformation (which was not initialized) will get the default value, which is null. This is the reason of the problem. You should change your if to enter to the code block if the value was found instead:
if (!SocketActivityInformation.AllSockets.TryGetValue(socketId, out socketInformation))
{
// Your code
}

Windows IOT UWP - Relay

Good Evening,
I’m doing some troubleshooting on the beginning of my home automation system. I am trying to toggle a relay using a Raspberry PI 3 and Windows IOT in C#. I’ve been playing with the code and I can see the relay toggle once or twice, but then the app crashes. I’m an IOT Noob, so is there something wrong with this code? (Variable names are defined elsewhere and the weird variable names I have below are for my WIP project... I prefer troubleshooting in English)....
private void BtnTempFan_Click(object sender, RoutedEventArgs e)
{
if (BtnTempFan.IsChecked == true)
{
TogglePin(TempFan, TempFan_PIN, BtnTempFan, GpioPinValue.High);
}
else
{
TempFan.Dispose();
}
}
private void TogglePin(GpioPin PinName, int PinNumber, ToggleButton Name, GpioPinValue value)
{
int pinnumber = PinNumber;
GpioPinValue pinvalue;
var gpio = GpioController.GetDefault();
PinName = gpio.OpenPin(pinnumber);
if (gpio == null)
{
PinName = null;
LblError.Text = "We can't find the controller on the device" + PinName;
LblError.Visibility = Visibility.Visible;
return;
}
if (PinName == null)
{
LblError.Text = "We can't find the pin on the device. Pin number " + PinNumber + "does not exist";
LblError.Visibility = Visibility.Visible;
return;
}
if (Name.IsChecked == true)
{
pinvalue = value;
PinName.Write(pinvalue);
PinName.SetDriveMode(GpioPinDriveMode.Output);
}
You don't say what the exception is. However, I believe you are supposed open a GPIO pin only once per app:
var gpio = GpioController.GetDefault();
PinName = gpio.OpenPin(pinnumber);
You have it in a method which is called once per button click. By opening the pin more than once, you are encountering that the pin is already open, and I believe this is what throws an exception and crashes the app.
In my code, I handle pin states in a "driver" class, and have a method called Connect which I call once when starting the application. For example:
public async Task Connect()
{
var gpioController = await GpioController.GetDefaultAsync();
try
{
_openPin = gpioController.OpenPin(_doorMotorOpenPin);
_closePin = gpioController.OpenPin(_doorMotorClosePin);
}
}
This encapsulates the 2 pins: _openPin and _closePin into a class that I can manage the lifecycle of.
Codekaizen is correct. I separated out opening the pin into a method that only gets called once and problem solved.
private void BtnTempFan_Click(object sender, RoutedEventArgs e)
{
if (BtnTempFan.IsChecked == false)
{
TogglePin(TempFan, TempFan_PIN, BtnTempFan, GpioPinValue.High);
}
if (BtnTempFan.IsChecked == true)
{
TogglePin(TempFan, TempFan_PIN, BtnTempFan, GpioPinValue.Low);
}
}
private void InitializePins()
{
var gpio = GpioController.GetDefault();
// Show an error if there is no GPIO controller
if (gpio == null)
{
TempFan = null;
LblError.Text = "We can't find the controller on the device";
LblError.Visibility = Visibility.Visible;
return;
}
TempFan = gpio.OpenPin(TempFan_PIN);
TempFan.SetDriveMode(GpioPinDriveMode.Output);
}
private void TogglePin(GpioPin PinName, int PinNumber, ToggleButton Name, GpioPinValue value)
{
int pinnumber = PinNumber;
GpioPinValue pinvalue;
pinvalue = value;
PinName.Write(pinvalue);
}

Send packets through internet using Pcapdotnet

I want to use pcapdotnet to send packet to my free web site, but there are no packets received, can any one tell me where is my fault,
my web site address: www.infinitypower.somee.com
I use ping to get the ip address: 204.27.56.226
the code:
using System;
namespace ClientApplication
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
fillDevice();
}
private void btnInvoke_Click(object sender, EventArgs e)
{
// Take the selected adapter
if (lsDevice.SelectedItem != null)
{
PcapDotNet.Core.PacketDevice selectedDevice = (PcapDotNet.Core.PacketDevice)lsDevice.SelectedItem;
// Open the output device
using (PcapDotNet.Core.PacketCommunicator communicator = selectedDevice.Open(100, PcapDotNet.Core.PacketDeviceOpenAttributes.Promiscuous, 1000))
{
communicator.SendPacket(BuildEthernetPacket());
}
}
else
MessageBox.Show("Select device from the list");
}
private void fillDevice()
{
lsDevice.Items.Clear();
IList allDevices = PcapDotNet.Core.LivePacketDevice.AllLocalMachine;
if (allDevices.Count == 0)
{
lsDevice.Items.Add("No interfaces found! Make sure WinPcap is installed.");
return;
}
// Print the list
for (int i = 0; i != allDevices.Count; ++i)
{
PcapDotNet.Core.LivePacketDevice device = allDevices[i];
lsDevice.Items.Add(device);
}
}
private PcapDotNet.Packets.Packet BuildEthernetPacket()
{
PcapDotNet.Packets.Ethernet.EthernetLayer ethernetLayer = new PcapDotNet.Packets.Ethernet.EthernetLayer();
ethernetLayer.Source = new PcapDotNet.Packets.Ethernet.MacAddress("01:02:03:04:05:06");
ethernetLayer.Destination = new PcapDotNet.Packets.Ethernet.MacAddress("01:02:03:04:05:67");
ethernetLayer.EtherType = PcapDotNet.Packets.Ethernet.EthernetType.IpV4;
ipV4Layer.CurrentDestination = new PcapDotNet.Packets.IpV4.IpV4Address("204.27.56.226");
ipV4Layer.Identification = (ushort)100;
PcapDotNet.Packets.PayloadLayer payloadLayer = new PcapDotNet.Packets.PayloadLayer();
payloadLayer.Data = new PcapDotNet.Packets.Datagram(System.Text.Encoding.UTF8.GetBytes(txPrayload.Text));
PcapDotNet.Packets.PacketBuilder builder = new PcapDotNet.Packets.PacketBuilder(ethernetLayer, ipv4layer, payloadLayer);
return builder.Build(DateTime.Now);
}
}
}

How to continuously ping and result changes an image

Hoping you can help me out here.
I am having a issue figuring out how to loop a piece of ping code and result ( if true or false ) changes an image.
here is my code running on a button click,
My aim here is to basically automise the app so the user does not have to click the refresh icon,
I have read a bit and am thinking I could use a while loop, But am unsure on how to use sleep with it.
The other method would be to use a thread with sleep?
I have also asked on MSDN to get the most feedback possible.
//Declaration of Global Variables (IP's)
public static string IP1, IP2, IP3;
//Method Setting Variables(IP's)
public static void setIP()
{
IP1 = Properties.Settings.Default.settingIP1;
IP2 = Properties.Settings.Default.settingIP2;
IP3 = Properties.Settings.Default.settingIP3;
}
//Method running Ping command
public static bool PingTest(string toPing)
{
string host = toPing;
bool result = false;
Ping p = new Ping();
try
{
PingReply reply = p.Send(host, 3000);
if (reply.Status == IPStatus.Success)
return true;
}
catch { }
return result;
}
//Refreshes IP1 then changes label to result
private void btnRefreshIP1_Click(object sender, RoutedEventArgs e)
{
setIP();
bool isConnected = false;
isConnected = PingTest(IP1);
if(isConnected == true)
{
lblsIP1.Foreground = Brushes.White;
lblsIP1.Content = "Online";
}
else
{
lblsIP1.Foreground = Brushes.Red;
lblsIP1.Content = "Offline";
}
}

Categories