|
Good catch. For a dedicated server machine that could be handy.
|
|
|
|
|
TCP the protocol (not TCPClient) for the most part does not do what you are asking.
And although Keep Alive is part of the protocol in general it is not going to be useful. Generally it won't even work unless you control the entire network infrastructure for all the components. And working doesn't mean it is useful.
If a connection pool is in use, then the properties of the connection pool dictate how idle connections are handled. If a connection pool is not in use then idle connections will not be closed (excluding a close from the client.)
A pool will close sockets that are in an error state or closed but that only happens after it is detected. Excluding a pool being configured to send a keep alive (probably not the same as the TCP Keep Alive) it relies on the user functionality to detect such errors. Pool keep alives can be considered to exist only in database pools as determining other types of keep alives depend on the client.
This has nothing to do with language/API either. But briefly looking at the docs for TCPClient I see nothing that suggests a pool is in use.
In general the only way to tell if a socket is still good is to send something and wait for it to indicate it went. This is not 100% but is generally sufficient especially if a reply is expected. Again this is how TCP works.
Additionally, and this impacts the point of Keep Alive (TCP protocol) the point is - why do you think this matters? What exactly are you gaining?
For example lets say you have a data center with two 24x7 servers that talk to each other.
From that the following scenarios exist.
- 99% of the time there is no problem.
- 0.99% of the time there is a socket closure caused by a scheduled bounce of one of the servers.
- 0.01% of the time the socket fails because of a 'network' failure which could include someone kicking out the power cord of one of the servers.
Now for the last case is can occur at ANY time. So the fact that a socket was 'alive' a minute ago doesn't help you any when you actually use it because it can fail when you use it. So the only way do deal with is either your code that USES the socket is written to deal with retries or you accept some infrequent processing errors (and other businesses process deal with it.)
Note that the second case can occur at any time as well.
Conversely the other 99.99% of the time you are now sending keep alives (not necessarily TCP) around the system to no purpose. Why no purpose? Because the system is up. So they don't do anything.
So you have useless traffic which doesn't keep you from writing code to deal with down time anyways.
(An additional considersation is what happens if the server on the other end gets the message but never does anything with it?
Grimes wrote: How can I get the connection to immediately throw the exception?
Presumably you mean for your test case - but in general the answer is you can't. The only way that happens if is the origination computer already knows that the other end is down. Which only happens if there was a previous error or it got a close from the server. Otherwise the origination MUST wait a non-trivial amount of time for a response. That is how TCP works.
If and ONLY if your computers are in a high quality data center then you can adjust the OS (OS, not app) configuration values to significantly reduce how long it waits. But on windows it cannot be reduced below 30 seconds.
Again this ONLY applies to server WITHIN a data center. It is completely inappropriate for the internet and is unlikely to be appropriate for a business lan.
Grimes wrote: Could there be a better way to fix this and to see if the connection has
closed?
Closed represents a happy path based on the target serving actually closing the socket. Other failure scenarios do not have anything to with closing the socket.
As an example if a router goes bad the path between the two servers can be unresolvable. Both servers are still up and think their sockets are good but one end never gets messages and the other end fails when it sends.
|
|
|
|
|
You make a very good point.
KOM UIT DAAAAA!!!
|
|
|
|
|
How to compare two dataTables in C#.
I have this code but it returns NULL.
DataTable dtReturn = new DataTable();
dtTarget.Merge(dtSource);
BindingContext[dtTarget].EndCurrentEdit();
dtReturn = new DataTable();
dtReturn = dtTarget.GetChanges(DataRowState.Added);
|
|
|
|
|
From what I read here[^], you need to switch the DataTable for the Merge function.
Try this:
dtSource.Merge(dtTarget);
DataTable dtReturn = dtTarget.GetChanges();
0100000101101110011001000111001011101001
|
|
|
|
|
Thanks for ans !
But even i have try this and returns NULL values too.
|
|
|
|
|
I just read this Comparing Datasets using Linq[^] and it states that
To resolve this issue we contacted the Microsoft Support team and after a few days of email exchange, we got the following message: ”I think the root of the issue is that Merge does not change row state. If you create a dataset, then manually change a row value, then row state is tweaked and GetChanges() behaves as expected.”
so it looks like the merge option is not going to work.
Perhaps you can use the LINQ option given.
0100000101101110011001000111001011101001
|
|
|
|
|
Hi,
I need some help for solving the following problem.
I got an event in C# an registered some methods to the event. I can fire them by calling the event with MyEvent().
eventDo += TestFkt;
eventDo();
It works fine.
The problem is the 'outsourcing' of the eventcall.
I want to register the methods to an event in C# but the event is fired within a C++ DLL with the command
SetEvent(HANDLE hEvent)
I can pass the hEvent via a DLL-call to the C++ code:
[DllImport("canapi2.dll", EntryPoint="CAN_SetClientParam")]
public static extern uint SetClientParam(
ushort wParam,
int dwValue);
The Method in the C++-Code to set the HANDLE hEvent
CAN_SetClientParam(
WORD wParam, DWORD dwValue);
In the C++-Code of the CAN-driver
SetEvent((HANDLE) dwValue)
is called while receiving CAN-Messages. With this call I want to inform the C#-Application.
Get anyone an idea, how to - let's say 'extract' - the Handle from the C#-event and pass it through the DLL?
Following code snippet doesn't work:
IntPtr iptr = Marshal.GetFunctionPointerForDelegate(eventDo);
SetClientParam(PARAM_ONRCV_EVENT_HANDLE, (int)(iptr));
Thanks for answering!
|
|
|
|
|
Firstly, if you have control over the C++ code, I would change the last parameter to a pointer type
CAN_SetClientParam(
WORD wParam, DWORD dwValue);
as it will work on a 32 bit system (DWORD is 32 bits) but possibly fail on a 64 bit system where a handle/pointer is 64 bits.
If I understand correctly, the C++ code calls the callback and you want to raise an event in C# on that callback?
That is quite easily done by creating a delegate with the correct signature for the C++ callback and just passing that directly in your C# prototype instead of marshalling. The function that the delegate points to can then raise an event as normal. Something like this (untested, written without an IDE so may have small errors!)
internal delegate void YourDelegate();
internal static class NativeMethods
{
[DllImport("canapi2.dll", EntryPoint="CAN_SetClientParam")]
public static extern uint SetClientParam(
ushort wParam,
YourDelegate dwValue);
}
public class YourWrapper
{
public event EventHandler YourEvent;
private YourDelegate yourDelegate;
private uint lastCallbackResult;
public YourWrapper()
{
yourDelegate = new YourDelegate(OnYourDelegate);
}
public uint LastCallbackResult
{
get{ return lastCallbackResult; }
}
public void CallUnmanaged(ushort wParam)
{
lastCallbackResult = NativeMethods.SetClientParam(wParam, yourDelegate);
}
private void OnYourDelegate()
{
OnYourEvent(EventArgs.Empty);
}
protected virtual void OnYourEvent(EventArgs e)
{
EventHandler eh = YourEvent;
if(eh != null)
eh(this, e);
}
}
You may need to change parameters, return types and possibly a custom EventArgs derived class to pass any data that is required from the callback, but the basic layout will be the same.
CallUnmanaged(); will trigger the C#/C++ interop and fire any handlers you attach to YourEvent , the callback result will be available in LastCallbackResult (I would move this to a custom event args rather that caching the value).
|
|
|
|
|
Do you got an idea why th applicatoin jumps never into OnYourDelegate after calling the SetEvent(..) in the DLL?
|
|
|
|
|
// C++ code:
BOOL manualReset = false;
HANDLE theEvent = CreateEvent(NULL, manualReset, false, _T("TheEvent"));
...
SetEvent(theEvent);
...
// C# code:
event EventHandler theEventTriggered;
...
theEventTriggered += SomeHandler;
...
EventWaitHandle theEvent = EventWaitHandle.OpenExisting("TheEvent");
theEvent.waitOne();
if (theEventTriggered != null)
{
theEventTriggered();
}
Note the C++ code must execute before the C# code that creates the event handle.
If it's the other way around, then simply use
new EventWaitHandle(false, EventResetMode.AutoReset, "TheEvent"); instead of
EventWaitHandle.OpenExisting("TheEvent");
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Thanks for the both answers!
@Dave
Your proposal and your code syntax ist just right! Compiles without any error and it hits my problem.
But in jumps never into OnYourDelegate after calling SetEvent(..) in the DLL.
@Ahmed
Is works fine, but if I did correctly understand, there's has to be a thread permenently running in the background to check up the call of the event!? When the event in the DLL raises, my own event 'theEventTriggered' is called from the thread.
It works fine, but I want to raise the Event in the C# code like an interrupt out of the DLL. Without permanently checking in a own thread. You see a possibility there?
I thought, I can give the DLL the adress of my C# event oder delegate. So, when the event in the DLL is fired, my event in C# is also fired. Like in the following way:
[DllImport("kernel32.dll", SetLastError = true, CallingConvention = CallingConvention.Winapi, CharSet = CharSet.Auto)]
public static extern IntPtr CreateEvent
(
IntPtr lpEventAttributes,
bool bManualReset,
bool bIntialState,
string lpName
);
public delegate void DoHandler();
public void Foo()
{
IntPtr EventsAdress = CreateEvent(IntPtr.Zero, false, false, "TheEvent");
DoHandler doH = new DoHandler(MethodForEventAction);
doH = (DoHandler)Marshal.GetDelegateForFunctionPointer(EventsAdress, typeof(DoHandler));
SetClientParam(wParam, EventsAdress );
}
public void MethodForEventAction()
{
Console.WriteLine("Event from DLL raised.");
}
SetEvent(EventsAdress);
Thanks for your input! Your suggestions are very useful. Do you got any idea about my second post?
|
|
|
|
|
Yes, you are correct that there needs to be a thread in the C# code waiting on the native kernel event to be triggered. That thread would then trigger the C# event or call the C# method. Note that the event or method would run in the context of the waiting thread.
You don't need to pass the event handle over to the C++ code or DLL. You just need to call CreatEvent with the same parameters and it will get a handle to the same event. Events created with CreateEvent are global to the system, and potentially accessible from any process.
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Thank you very much. It works.
IntPtr MsgReceivedEvent
MsgReceivedEvent = CreateEvent(IntPtr.Zero, false, false, "RcvEvent");
startRcv((uint)MsgReceivedEvent);
EventWaitHandle theEvent = EventWaitHandle.OpenExisting("RcvEvent");
while (!PendingCancel)
{
if (theEvent.WaitOne(5000))
{
Log("EVENT RAISED!");
}
}
SetEvent(MsgReceivedEvent);
|
|
|
|
|
Excellent! Glad I could be of help!
If your actions inspire others to dream more, learn more, do more and become more, you are a leader." - John Quincy Adams You must accept one of two basic premises: Either we are alone in the universe, or we are not alone in the universe. And either way, the implications are staggering” - Wernher von Braun
|
|
|
|
|
Hi
I want to highlight or more like select all the occurrences of a word. But I have googled a lot and haven't found anything about that.
When I have tried, it just selects one appearance of the word, the last.
Word.Application ap = new Word.Application();
doc = ap.Documents.Open(path, ReadOnly: false, Visible: true);
ap.Selection.Find.ClearFormatting();
ap.Selection.Find.Text = txtFind.Text;
ap.Selection.Find.Execute();
while (ap.Selection.Find.Found)
{
ap.Selection.Select();
ap.Selection.Find.Execute();
}
doc.Activate();
ap.Visible = true;
ap.ActiveWindow.SetFocus();
I have tried so many different approaches, but haven't been able to solve it.
I don't want to highlight the words, I just want them to be selected as they are when you choose find all in Microft Word.
Hope somebody can help me.
Many thanks
Fia
|
|
|
|
|
You are missing some properties for your Selection.Find list. Try setting Forward = true and Wrap = wdFindContinue . To find these values, you can use the macro recorder in Word and perform a Find all operation - this should give you a good place to start.
|
|
|
|
|
Hi
Thanks for your reply, but I have already tried that, but nothing changes. It just selects the last occurrence of the word. I really don't want to use a macro. Aren't there another way to accomplish this.
Many thanks
Fia
|
|
|
|
|
Use the macro to tell you what options to set, not to actually run the find.
|
|
|
|
|
Hi
Thank you, that was smart. But when I record a macro that does what I want and later tries to run the macro nothing happens. I don't understand why?
Do you have anymore suggestions.
Many thanks
Fia
|
|
|
|
|
fiaolle wrote: It just selects the last occurrence of the word.
May be you have to set MultiSelect = true somewhere in your code. Just a suggestion though, I haven't done Word automation so far.
|
|
|
|
|
Repeating what was already said....
1. Create a macro that does what you want.
2. LOOK at the macro. Figure out what it is doing.
3. Use the information that you LEARNed in 2 to create your C# code.
|
|
|
|
|
Hi
I have already tried that but it doesn't work. I have no idea how to solve this. If anyone knows please help.
Thanks
Fia
|
|
|
|
|
Is there a way to run nunit Test class 50 times in a loop ?
For example I have a class like
[TestFixture]
public class DemoFailureTeste
Can I run it 50 times successively ?
modified 10-Oct-11 7:11am.
|
|
|
|
|
Of course you can. Just move the code that you want testing into a for loop. I would probably move it into a method on its own and just call that from the loop if I were you.
|
|
|
|