Inconsistent behavior from ServicePointManager.SetTcpKeepAlive - c#

I've been trying to get tcp keep alive packets to send using System.Net.Http.HttpClient. As far as I can see the only way to do this is using ServicePointManager.SetTcpKeepAlive(true, X, Y). When testing this in a LinqPad script I have got it working although it's not consistent. For example if I do a manual call to ServicePointManager.FindServicePoint(myUrl) before I call ServicePointManager.SetTcpKeepAlive then it won't work, I assume because of caching, however if it's the first thing that happens it usually works (I'm fairly certain it's still inconsistent here). Note that I am checking whether it works or not using Wireshark.
However when I try to use this in my real UWP application it fails. I've tried setting this as the first App.xaml.cs constructor and just before instantiating the HttpClient and various places in between without any luck.
Am I missing something?
Note that I realise it is possible to use HttpWebRequest directly and set this on it's ServicePoint instance but I'd like to know why this isn't working first before resorting to something like this.
EDIT: I ended up trying to implement this with HttpWebRequest and ServicePoint.SetTcpKeepAlive and while it compiles, it fails when it's called with a Operation is not supported on this platform exception. I guess this means the main problem here might be that UWP just doesn't support sending TCP keep alive packets?
EDIT2: I've created a minimum reproducible example here: https://github.com/csuzw/TcpKeepAliveTest . In this case the HttpWebRequest approach does not fail with the Operation is not support on this platform exception but it doesn't send keep alive packets either. I wonder if the difference is that my real app is a Xamarin.Forms UWP target app, whereas this test app is a straight UWP app. Regardless both approaches used in this test app fail to produce keep alive packets.

Related

Monitoring disconnects in QuickFIX/n

Working with QuickFIX/n and need to find a way to monitor potential crashes on the executor side (I am developing the client side). I see there is logging when a connection stops but no way of tracking and triggering anything in the code.
I have looked at Quickfix/n - No event for connection timeout or host not found? but it only addresses initial connection, not crashes post connection. QuickFIX/J has SessionStateListener https://quickfixj.org/javadoc/1.6.4/quickfix/SessionStateListener.html but not finding anything similar in the C# variant.
Basically, need to find a way to create an observer but do not see anything built in that could be of use.
This isn't a definitive solution but ends justify the means for now.
Have created own implementation of the ILogFactory (rather than use builtins) and it listens to the message containing " disconnecting: " then sends info to applicable services. Causes some strange coupling but currently not seeing a clean way like the java implementation does it.

Problems using a DLL with WPF - AccessViolationException

I'm trying to use Microchip's Managed DLL with their MCP2210 Evaluation Kit. I was having success with sing it with a Console Application - I can change what LED is lit via the Potentiometer and I can read the temperature. However, I'm having issues using it under WPF.
I'm using the exact same code to fetch values off of the device, however I'm running across AccessViolationExceptions and now SEHExceptions. Would using a threaded approach to continually poll the device cause memory to corrupt? And how can I avoid doing that?
So I think I figured out the issue. Maybe.
I tried using lock to make sure that only one thread's accessing the device at any one time, and that seems to have cleared up all of the issues thus far. Still need to perform more testing, but it's working so far.

SslStream responds differently when accessed as COM object

I am working with an on a project where the bulk of the code is C++. The shop is migrating to C# in the long run, so where possible we are making new code in C# and exposing to C++ via COM.
I have wrapped an System.Net.Sockets.SslStream and a little bit of other functionality in a COM object that is intended to send and then receive messages. When calling the functions on this class from a test C# program I am able to send and receive messages without issue. Making the same calls, which are exposed via COM, seems to work as well, except I cannot receive data immediately after I send.
From the C# test data sends and receives quite quickly and I get the responses I should. From C++ I always get timeout errors. The data in the functions making the call to Read is identical in the C# test and from the C++ program. Much of the state in the SslStream is identical. Just after the write call and before the Read the only differences appear to be, several handles and what appear to be memory addressest, but I assume those are not important. At this same time I noticed that in an item called 'base', then inside an item called 'InnerStream', then inside 'System.Net.Sockets.NetworkStream' there is a property called 'DataAvailable'. This is true in the C# test where it works and false in the C++ program where it fails. I am not aware of any meaningful difference between these project beyond what I have described.
I can provide further details about troubleshooting or snippets of code. I have not included code here because tjust the pieces related to the problem would still be immense. I hope there is some kind of magic answer as to what is going on, however the error is almost certainly in depth and very specific. I would appreciate anything that provides insight on further troubleshooting steps.
What kinds of complications does calling C# though COM impose that I may not have taken in account?
Where did the other sides message go if not into the SslStream buffer?
Where should I be looking?
I have discovered the answer, and it is unrelated to COM, C#, C++ and instead has to do with the formatting of the message being sent between the systems involved. The other system uses an extra carriage return to indicate the end of the message. When missing the remote system simply stops responding until another SSL session is started.
At a previous point in the project I was including an extra line break at the end of messages sent to the server. I had copied one of these messages to produce my entirely c# test. Several times I also took the messages being sent from both codebases and put them into a merge/diff viewer. I never noticed this difference because I had disabled white space matching.
From now on when I compare raw output to other raw output, I will make sure that none of my tools will hide differences from me.

What makes my program work with a delay on windows startup?

My program starts with windows startup,
But a background worker is supposed to work instantly after the program is opened.
But it starts with a delay and then even returns false signs(it returns if a site is up),
Only after about 15 seconds the background-worker continues to work normally and the program too. I think this is because of .net framework trying to load, or internet connection that is not up yet, or something that didn't load yet(windows startup).
What can solve this, and what is the probable cause? (WinForm C#)
Edit:
Here is something I thought of,
I don't think though that this is a good practice. Is there a better way?
(Load method):
while (!netConnection())
{
}
if(netConnection())
bwCheck.RunWorkerAsync();
I think this is because of .net framework trying to load
Nope. If that were the case your program wouldn't run.
or internet connection that is not up yet, or
Yup. The network card/interface/connection/whatever is not initialized and connected to the internet yet. You can't expect a PC to be connected to the internet immediately at startup. Even more, what if your customer is on a domain using network authentication? What if they delay network communications until some task is complete (this was actually the problem in my case below. Seriously.)
It may take even longer to get it up and running in that case (read: don't add a Thread.Sleep() in a vain attempt to 'fix' the issue.
I had to fix a problem like this once in a systems design where we communicated to a motion control board via the ethernet bus in a PC. I ended up adding some code to monitor the status of the network connection and, only when it was established, started talking to the device via the network card.
EDIT: As SLaks pointed out in the comments, this is pretty simple in C#: The NetworkAvailabilityChanged event for your programming pleasure.
It is absolutely because of everything still starting up. Services can still be coming online long after you log in, the quick login dialog you see was an optimization in windows to let you log in while everything else still starts up.
Take note of
How to detect working internet connection in C#?
specifically a technique that avoids the loopback adapter:
System.Net.NetworkInformation.NetworkInterface.GetIsNetworkAvailable()

Is SmsMessage not thread-safe?

I'm writing an app for WM that handles incoming SMS events. I tried making it multi-threaded (using ThreadPool.QueueWorkItem) where the SmsMessage was passed along. However, I noticed that when I did that, the program would only handle the first sms event - afterwards, NO SMS were received by the device at all! But when the program exits, then all the missed SMSs arrived.
Based on that, I'd guess that the answer to my question is that SmsMessage objects are NOT thread-safe, even though there's not really an indication that that's the case.
So what if we want to try and thread an SmsMessage Object? I'll try that out tonight by making a copy of the SmsMessage (probably by using the constructor w/ item id), or I'll create an empty one and copy the fields manually.
DISCOVERY:
I narrowed down my problem. I was able to get everything to work in a background thread when I copied the SmsMessage into my own object, taking care not to reference any of the SmsMessage's objects. SMSs went flying through with no problem.
However, when I set up an MessageIntercepter to launch an application, and within that application instance, use a background thread to send an SMS, the application would work fine, but after it exits my code it crashes and displays the "There was an error in yourapp.exe" and asks me if you want to send the crash data to MS. I could never figure out what that error was, but I found out that if I sent the SMS from the same thread that launched the application, everything worked fine.
So, threading when the app is open = fine, as long as you don't pass/use the SmsMessage
Threading when the app is externally launched = fine, as long as you don't send an SmsMessage in another thread.
According to the MSDN Library (Microsoft.WindowsMobile.PocketOutlook.SmsMessage):
Any public static (Shared in Visual
Basic) members of this type are
thread-safe. Any instance members are
not guaranteed to be thread-safe.
So the answer to your question is: it is not thread-safe.
EDIT: I'm glad you managed to get this thing working. I'm pretty sure it's some race condition or unmanaged resource handling issue deep down in the PocketOutlook library.
Personally, I think you should keep all your messaging-related code in a single thread, from the point the MessageInterceptor created until the point it gets disposed and only pass objects that are written by you so you know that they don't have dodgy unmanaged dependecies (that's kind of what you did I think) - this should be enough to avoid these problems.
What's the point of having 2 SMS interceptor threads anyway? It's not like a phone could receive 2 text messages the same time.
Without seeing more code, it's hard to guess what's happening. I strongly suspect that it was a problem with your threading code rather than with SmsMessage.
If you could explain the architecture of your application, that would help a lot. I wouldn't be surprised to find you'd got a deadlock somewhere which was blocking everything.

Categories