Interrupt a running process with IPC - c#

I have two processes in a Win Form application. In the first process I have a methode "checkIfTrue" which has a return value of boolean. The methode in the first process will get some information from the second process by IPC (I use WCF with named pipes) and will return, depand on the information from the second process true or false.
My problem how can I interrupt the first process? The method in the first process ask the second process for information, when the second process got the information and will send back the result to the first process. In the first process the result will not be process before the methode "checkIfTrue" are finished.
The second process will call a method "synchronizeResults" via IPC and transfer the results. The methode "synchronizeResults" store the result in a ConcurrentDictionary. My plan was to stop the methode "checkIfTrue" in first process until the Dictionary is filled. But the methode "synchronizeResults" is not calling by IPC until methode "checkIfTrue" is finished.
Normally i would fire a event when the result are send back from process 2, but in this case I need the result before the methode is finished.

The main reason while it doesnt work was my CallbackService-Class. I had forgot to mark the class with
[CallbackBehavior(UseSynchronizationContext = false, ConcurrencyMode = ConcurrencyMode.Multiple)].
When a callback is made from the service to client, only one thread is spawned because by default the concurrency mode is set to “single”.
Here's [a link] (https://blogs.msdn.microsoft.com/dsnotes/2013/09/18/wcf-callback-operations-are-invoked-sequentially/)

Related

ohLibspotify not calling any callback after login

I'm trying to create a project where I use the ohLibspotify .Net libspotify wrapper to login to spotify and stream playlists.
As far as I can see I've set everything up the same way like in the example. First create a session like so:
SpotifySessionConfig sp_config = new SpotifySessionConfig()
{
ApiVersion = 12,
CacheLocation = "cache",
SettingsLocation = "settings",
UserAgent = "player",
ApplicationKey = Properties.Resources.appkey,
Listener = new sp_Listener()
};
sp_session = SpotifySession.Create(sp_config);
Then I call relogin() if that fails than I show the login window to the user because no stored credentials have been found. When the user has supplied me with his account details I call login(username, password, true, null). After that I'm awaiting a call back to the sp_Listener class.
In the sp_Listener class I have overridden the following functions:
SpotifySessionListener.LoggedIn(SpotifySession session, SpotifyError error)
SpotifySessionListener.ConnectionError(SpotifySession session, SpotifyError error)
SpotifySessionListener.LogMessage(SpotifySession session, string data)
The only callback that gets called is the LogMessage callback. I've hooked it up to log4net to read all the output efficiently. This is all of the LogMessageoutput:
2015-02-22 20:58:38,636 [18] DEBUG Namespace.sp_Listener - 19:58:38.634 I [c:/Users/spotify-buildagent/BuildAgent/work/1e0ce8a77adfb2dc/client/core/session/offline_authorizer.cpp:297] Unable to login offline: no such user
2015-02-22 20:58:38,649 [18] DEBUG Namespace.sp_Listener - 19:58:38.649 I [c:/Users/spotify-buildagent/BuildAgent/work/1e0ce8a77adfb2dc/client/core/session/offline_authorizer.cpp:297] Unable to login offline: no such user
2015-02-22 20:58:38,651 [14] DEBUG Namespace.sp_Listener - 19:58:38.649 E [c:/Users/spotify-buildagent/BuildAgent/work/1e0ce8a77adfb2dc/client/core/network/proxy_resolver_win32.cpp:215] WinHttpGetProxyForUrl failed
2015-02-22 20:58:38,664 [19] DEBUG Namespace.sp_Listener - 19:58:38.661 I [ap:1752] Connecting to AP ap.gslb.spotify.com:4070
2015-02-22 20:58:38,713 [19] DEBUG Namespace.sp_Listener - 19:58:38.713 I [ap:1226] Connected to AP: 193.182.7.34:4070
It seems like I must have forgotten something. I've no idea what, maybe one of you guys knows a solution.
I'm the original author of the ohLibSpotify wrapper library. I think you possibly have overlooked the need to call ProcessEvents. ohLibSpotify tries as far as possible to provide only a thin layer over libspotify. Almost everything in the libspotify docs remains relevant when you are using ohLibSpotify, and you should consider those docs your first port-of-call. https://developer.spotify.com/docs/libspotify/12.1.51/index.html
In particular:
The library itself uses multiple threads internally. To allow for synchronization between these threads, you must implement the sp_session_callbacks::notify_main_thread callback. Whenever called (from some internal thread), the application must wake up the main loop so the sp_session_process_events() function can be run.
The API itself is not thread-safe. Thus, you must take care not to call the API functions from more than one of your own threads.
The names are slightly different, but the concepts are the same - you need to implement NotifyMainThread to get notifications that libspotify wants to communicate with you, then you need to make sure that your main thread calls sp_session.ProcessEvents. You also need to make sure that only one thread ever interacts with ohLibSpotify at a time, either by coordinating so that only one thread calls ohLibSpotify, or by using appropriate locks around calls into ohLibSpotify.
(I'm using libspotify names here: the following advice applies equally whether you're using libspotify directory or ohLibSpotify.)
With a few exceptions, libspotify only ever calls your callbacks from inside a call to sp_session_process_events. (The exceptions are notify_main_thread and the callbacks associated with music delivery.) So if you're not set up to call that regularly, you'll find that libspotify doesn't do very much. If your program has an event loop, you should arrange to send yourself events whenever you receive the notify_main_thread callback or when the time specified by your last call to sp_session_process_events has passed, and call sp_session_process_events in the event handler. If you have no event loop, you might want to spawn a thread for this purpose, and make sure to use appropriate locks to stop other threads from calling into libspotify at the same time.

C# .net 3.5 inter process communication verify the child process has started ok

I have parent process that use process.start(..) for a another process.
The child process will later on have WCF service that i call an Initialized() on it.
Before calling any methods, I would like to verify and make sure the process has started ok.
right now my code is:
Process driverProcess = new Process();
driverProcess.StartInfo.FileName = ".."
driverProcess.Start();
and then i use my WCF Service client:
client.Initialize(..);
It is working since process is starting ok, but i dont have any indication for this.
E.g if the computer does not allow to start new process, the Process.Start() wont work, and my client will try to .initialize() an non-existing WCF service.
What technique can i use in order to know the process has started ? Named pipes client-server?
I CANT use process.WaitForInputIdle() since this is Winform application that i removed the form1() from it. "Gui less window application".
What I used in the end was EventWaitHandle.
I named the event on Parent process with its process Id, when I created the child process, I sent as arg the parent process Id.
When child process finishes its initialization, It creates a new ManualResetEvent with same name (parent process id from arg[0]) and .Set() it.
Parent Process code:
Process newProcess= new Process();
newProcess.StartInfo.FileName = "YourProcessPath+FileName.exe" //use CombinePath
newProcess.StartInfo.Arguments = string.Format("{0}", Process.GetCurrentProcess().Id);
var handle = new EventWaitHandle(false, EventResetMode.AutoReset, Process.GetCurrentProcess().Id.ToString());
handle.Reset();
handle.WaitOne(); //wait until event is Set() from child Process
Code in child process:
signalParentProcessImReady = new EventWaitHandle(false, EventResetMode.AutoReset, args[0]);
DoWwork()... initialize WCF Services for example...
signalParentProcessImReady .Set(); //Signal parent process Im ready
You can check the boolean value of the Start() method. Besides you can associate an Exited event handler to the process to tell your app that the app has finished. This way you can also know if it started and ended right after.
EDIT: i forgot to mention that you can also put your starting code inside a try block and check for exceptions that might be thrown by Start() method.

starting external process when one process is done

Stupid question, but I am starting a couple external applications (all .exe). After the process is started, how can I make my program wait until that process ends to start another process?
Example'
'Start application
Process.Start(My.Computer.FileSystem.CurrentDirectory & "SomeEXE1.exe")
**' A if statement or something to state that SomeEXE2.exe will NOT start until SomeEXE1.exe finish.**
Process.Start(My.Computer.FileSystem.CurrentDirectory & "SomeEXE2.exe")
Just call:
Process.WaitForExit
on that instance of Process.
How about using Shell?
Dim pID As Integer = Shell(thePathOfEXE, AppWinStyle.NormalFocus, True, 30000)
Will launch the exe passing the processID back to pID, normal focus and wait until completed execution or until 30 seconds have passed. The 30000 could be -1 if you're not interested in a timeout.
http://msdn.microsoft.com/en-us/library/xe736fyk(v=vs.71).aspx

C# threading help needed

I've been asked to write a method that will allow a caller to send a command string to a hardware device via the serial port. After sending the command the method must wait for a response from the device, which it then returns to the caller.
To complicate things the hardware device periodically sends unsolicited packets of data to the PC (data that the app must store for reporting). So when I send a serial command, I may receive one or more data packets before receiving the command response.
Other considerations: there may be multiple clients sending serial commands potentially at the same time as this method will form the basis of a WCF service. Also, the method needs to be synchronous (for reasons I won't go into here), so that rules out using a callback to return the response to the client.
Regarding the "multiple clients", I was planning to use a BlockingCollection<> to queue the incoming commands, with a background thread that executes the tasks one at a time, thus avoiding serial port contention.
However I'm not sure how to deal with the incoming serial data. My initial thoughts were to have another background thread that continually reads the serial port, storing data analysis packets, but also looking for command responses. When one is received the thread would somehow return the response data to the method that originally sent the serial command (which has been waiting ever since doing so - remember I have a stipulation that the method is synchronous).
It's this last bit I'm unsure of - how can I get my method to wait until the background thread has received the command's response? And how can I pass the response from the background thread to my waiting method, so it can return it to the caller? I'm new to threading so am I going about this the wrong way?
Thanks in advance
Andy
First of all: When you use the SerialPort class that comes with the framework, the data received event is asynchronous already. When you send something, data is coming in asynchronously.
What I'd try is: queue all requests that need to wait for an answer. In the overall receive handler, check whether the incoming data is the answer for one of the requests. If so, store the reply along with the request information (create some kind of state class for that). All other incoming data is handled normally.
So, how to make the requests wait for an answer? The call that is to send the command and return the reply would create the state object, queue it and also monitor the object to see whether an answer was received. If an answer was received, the call returns the result.
A possible outline could be:
string SendAndWait(string command)
{
StateObject state = new StateObject(command);
state.ReplyReceived = new ManualResetEvent(false);
try
{
SerialPortHandler.Instance.SendRequest(command, state);
state.ReplyReceived.WaitOne();
}
finally
{
state.ReplyReceived.Close();
}
return state.Reply;
}
What's SerialPortHandler? I'd make this a singleton class which contains an Instance property to access the singleton instance. This class does all the serial port stuff. It should also contain an event that is raised when "out of band" information comes in (data that is not a reply to a command).
It also contains the SendRequest method which sends the command to the serial device, stores the state object in an internal list, waits for the command's reply to come in and updates the state object with the reply.
The state object contains a wait handle called ReplyReceived which is set by the SerialPortHandler after it has changed the state object's Reply property. That way you don't need a loop and Thread.Sleep. Also, instead of calling WaitOne() you could call WaitOne(timeout) with timeout being a number of milliseconds to wait for the reply to come in. This way you could implement some kind of timeout-feature.
This is how it could look in SerialPortHandler:
void HandlePossibleCommandReply(string reply)
{
StateObject state = FindStateObjectForReply(reply);
if (state != null)
{
state.Reply = reply;
state.ReplyReceived.Set();
m_internalStateList.Remove(state);
}
}
Please note: This is what I'd try to start with. I'm sure this can be very much optimized, but as you see there's not much "multithreading" involved where - only the SendAndWait method should be called in a way so that multiple clients can issue commands while another client is still waiting for its response.
EDIT
Another note: You're saying that the method should form the basis for a WCF service. This makes things easier, as if you configure the service right, a instance of the service class will be created for every call to the service, so the SendAndWait method would "live" in its own instance of the service and doesn't even need to be re-entrant at all. In that case, you just need to make sure that the SerialPortHandler is always active (=> is created and running independently from the actual WCF service), no matter whether there's currently an instance of your service class at all.
EDIT 2
I changed my sample code to not loop and sleep as suggested in the comments.
If you really want to block until the background thread has received your command response, you could look into having the background thread lock an object when you enqueue your command and return that to you. Next, you wait for the lock and continue:
// in main code:
var locker = mySerialManager.Enquee(command);
lock (locker)
{
// this will only be executed, when mySerialManager unlocks the lock
}
// in SerialManager
public object Enqueue(object command)
{
var locker = new Object();
Monitor.Enter(locker);
// NOTE: Monitor.Exit() gets called when command result
// arrives on serial port
EnqueueCommand(command, locker);
return locker;
}
A couple things. You need to be able to tie up serial responses to the commands that requested them. I assume that there's some index or sequence number that goes out with the command and comes back in the response?
Given that, you should be OK. You need some sort of 'serialAPU' class to represent the request and response. I don't know what these are, maybe just strings, I don't know. The class should have an autoResetEvent as well. Anyway, in your 'DoSerialProtocol()' function, create a serialAPU, load it up with request data, queue it off to the serial thread and wait on the autoResetEvent. When the thread gets the serialAPU, it can store an index/sequence number in the serialAPU, store the serialAPU in a vector and send off the request.
When data comes in, do you protocol stuff and, if the data is a valid response, get the index/sequence from the data and look up the matching value in the serialAPU's in the vector. Remove the matching serialAPU from the vector, load it up with the response data and signal the autoResetEvent. The thread that called 'DoSerialProtocol()' originally will then run on and can handle the response data.
There are lots of 'wiggles' of course. Timeouts is one. I would be tempted to have a state enum in the serialAPU, protected by a CritcalSection or atomicCompareandSwap, initialized ot 'Esubmitted'. If the oringinating thread times out its wait on the autoResetEvent, it tries to set the state enum in its serialAPU to 'EtimedOut'. If it succeeds, fine, it returns an error to the caller. Simlarly, in the serial thread, if it finds a serialAPU whose state is EtimedOut, it just removes it from the container. If it finds the serialAPU that matches response data, it tries to change the state to 'EdataRx' and if it succeeds. fires the autoRestEvent.
Another is the annoying OOB data. If that comes in, create a serialAPU, load in the OOB data, set the state to 'EOOBdata' and call some 'OOBevent' with it.
I would advise you to look at the BackgroundWorker-Class
Ther is a Event in this class (RunWorkerCompleted) which is fired when the worker has finished his job.

C# Stopping TCP File Transfer

I'm programming simple TCP file transfer using TcpListener on reciever side and TcpClient on sender side. I have 2 options - synchronnous or asynchronnous. If I use synchronnous, I have to put sending/recieving methods into BackgroundWorker, to prevent freezing GUI thread. Asynchronnous version is without problems...
My question is, how to stop running file transfer?
In synchronnous version I tried to use BackgroundWorker.CancelAsync() method, and in every loop iteration check BackgroundWorker.CancellationPending property, but it doesn't seems to work (CancelAsync is probably not setting CancellationPending property) :(
In asynchronnous version I tried to use volatile variable Indicator and in every Callback check its value. Problem is, when I change its value in Stop() method, and than I check it in Callback, callback still reads its previous value :(
CancelASync should work; did you set:
backgroundWorker.WorkerSupportsCancellation = true:
Are you saying that you aren't reading the correct "cancel state" when you check it? This suggests you're not synchronising the flag between your threads correctly.
Or is it just that you won't ever check for the "cancel state" unless you receive some new data? (From the way you describe your tx/rx "loops", in both sync and async cases you will have to receive a new datagram before you will get a chance to check the 'cancel' flag)
If you are in control of both ends of the data transfer, then whichever end (client or server) wishes to abort should ideally send a special datagram to the other end to stop the transfer - otherwise the other end will attempt to continue sending/receiving, not knowing that it's on its own. So perhaps a better approach would be to actually send/receive a "cancel transfer" datagram, which would inform the TCP code at both ends that you wish to cancel. (i.e. you wouldn't need to have a special cancel flag, you would simply check if the datagram you are about to send or have just received is a "cancel transfer" datagram). This would allow both ends to gracefully and cleanly close down.

Categories