Remove particular class's completion handler from array - swift3

I have implemented one method of completion handler which fetch data from server.
While one request is in progress, this method may be called multiple time by any other class and I want to notify all once data is received from server without sending multiple request.
To achieve this I am adding up completion handlers in thread safe array.
But I want to remove particular completion handler if caller class doesn't exists in memory when data is received from server.
Ex - If controller's viewDidDisAppear() gets called. I want to removed its handler.
How to achieve this?

Related

Does SendAsyncCancel cancel SendMailAsync?

In the SmtpClient class, does SendAsyncCancel cancel the SendMailAsync method?
I see a few code examples on the www which imply it does.
However MSDN says,
Use the SendAsyncCancel method to cancel a pending SendAsync operation. If there is mail waiting to be sent, this method releases resources used to store the mail. If there is no mail waiting to be sent, this method does nothing.
... which implies that it cancels SendAsync but not SendMailAsync.
Is there a way to cancel SendMailAsync? If not, why not?
If you want to cancel an asynchronous send (therefore use the old SendAsync instead of the newer SendMailAsync), what are any other disadvantages of using SendAsync instead of SendMailAsync?
I tried to invoke SendMailAsync from a post-back handler of an ASP web page, and it threw an exception:
System.InvalidOperationException: Asynchronous operations are not allowed in this context. Page starting an asynchronous operation has to have the Async attribute set to true and an asynchronous operation can only be started on a page prior to PreRenderComplete event.
at System.Web.LegacyAspNetSynchronizationContext.OperationStarted()
at System.ComponentModel.AsyncOperation.CreateOperation(Object userSuppliedState, SynchronizationContext syncContext)
at System.Net.Mail.SmtpClient.SendAsync(MailMessage message, Object userToken)
--- End of inner exception stack trace ---
at System.Net.Mail.SmtpClient.SendAsync(MailMessage message, Object userToken)
at System.Net.Mail.SmtpClient.SendMailAsync(MailMessage message)
at MyWebSite.AdminTest.TestEmail.<sendAsynchronous>d__9.MoveNext()
From this I deduce two things:
SendMailAsync is indeed implemented using SendAsync (you can see it on the call-stack of the exception). SendAsyncCancel therefore will presumably work for SendMailAsync too.
You can't call SendMailAsync from an ASP unless you want to deal with the "Asynchronous operations are not allowed in this context" problem. That's discussed here and looks like it might be messy. Whereas I guess that calling SendAsync probably doesn't have this problem (because I'm using HttpClient.SendAsync and ContinueWith elsewhere, with a CountdownEvent.Wait at the end to wait for the operation to complete, without seeing this exception being thrown).
SendMailAsync can be used when it's invoked via HostingEnvironment.QueueBackgroundWorkItem.

C++ Multi threaded socket operation with progress bar update

I have a MFC DLL that I am implementing. The main thread creates a progress bar (CProgressCtrl) and then starts a CWinThread to perform some socket operation. The idea is to have the main thread update the progress bar while the other thread performs sendto socket operation (data request) to request data. Here is the issue though, due to legacy implementation, the receive capability is done via overriding OnReceive function of CAsyncSocket. When OnReceive is called, the code simply copies the data into its own buffer and allow another function to process later.
Currently, the other thread that is doing the sendto operation (data request) is activity checking the buffer to see if the sequence number has been incremented. This all worked fine when the sendto operation is within the main thread (this means UI will freeze), but after I relocated the sendto operations to another thread, the OnReceive is no longer being called even when the data is sent from the other software(verified).
My question is that why is OnReceive not being called when the other side is clearly sending data? I understand this might not be the optimal design but due to legacy design, i would like to keep the current design.
CASyncSocket is bound to the thread in which it is created. Only that thread can receive the OnReceive notification.

DBUS - multithread processing

I have a main loop in my program, which calls this method from dbus:
dbus_connection_read_write_dispatch
I have some registered callbacks, which are invoked, when message arrives. Within this callback I am also processing the response and sending back response. Problem is that sometimes it takes much time so probably it will block receiving messages from DBUS.
Question - can I call dbus_connection_read_write_dispatch() method on the same connection from more than one thread? Then it will be probably possible to receive new DBUS messages while the previous one is being processed.
Or maybe better idea is to process responses in another thread than the main loop, from callback is invoked?
Thank you
you can call dbus_connection_read_write_dispatch() from multiple threads if you have called the function dbus_threads_init_default() atleast once.Instead a better approach is to have a single thread running dbus dispatcher and use a thread-pool to process the data from callbacks.
See dbus_threads_init_default() for more info.
By the document provided by freedesktop.org, you can.
But if you operate with same DBusConnection instance from different threads directly, eg. calling dbus_connection_send_with_reply_and_block in a thread while anothoer thread is blocking on dbus_connection_read_write_dispatch, the connection maybe work unproperly. According to official document, DBus connection will be locked when calling callback functions.DBusConnection
In my situation, the dbus_connection_send_with_reply_and_block didn't return even if the return message was send to my process (I had seen it on dbus-monitor). Calling dbus_thread_init does not work at all.
Recently I used a delegate to send / receive / dispatch all dbus messages in one thread, and problem disappeared.
A mail in mailing list of freedesktop.org

Difference between smtpClient.send() and smtpClient.SendAsync()?

I am trying to send mail from localhost..
and on doing this i have got methods from different sites to sending mails..but on doing this i am confused between smtpClient.send() and smtpClient.SendAsync()..
I want to know that How they are different from each other???
Thanks in advance..
smtpClient.send() will initiate the sending on the main/ui thread and would block. smtpClient.SendAsync() will pick a thread from the .NET Thread Pool and execute the method on that thread. So your main UI will not hang or block.
Async Method Invocation - http://www.codeproject.com/KB/cs/AsyncMethodInvocation.aspx
SendAsyc - Sends the specified e-mail message to an SMTP server for delivery. This method does not block the calling thread and allows the caller to pass an object to the method that is invoked when the operation completes. More details : SmtpClient.SendAsync Method

Event-Driven Client/Server Design with C++

I am designing a game server with scripting capabilities. The general design goes like this:
Client connects to Server,
Server initializes Client,
Server sends Client to EventManager (separate thread, uses libevent),
EventManager receives receive Event from Client socket,
Client manages what it received via callbacks.
Now the last part is what's the most tricky for me now.
Currently my design allows me for a class which inherits Client to create callbacks to specific received events. These callbacks are managed in a list and the received buffer goes through a parsing process each time something is received. If the buffer is valid, the callback is called where it is act upon what is in the buffer. One thing to note is that the callbacks can go down to the scripting engine, at which point nothing is sure what can happen.
Each time a callback finishes, the current receive buffer has to be reset etc. Callbacks currently have no capability of returning a value, because as stated before, anything can happen.
What happens is that when somewhere in the callback something says this->disconnect(), I want to immediately disconnect the Client, remove it from the EventManager, and lastly remove it from the Server, where it also should get finally destructed and free memory. However, I still have some Code running after the callback finishes in the Client, thus I can't free memory.
What should I change in the design? Should I have some timed event in the Server which checks which Clients are free to destroy? Would that create additional overhead I don't need? Would it still be okay after the callback finishes to run minimal code on the stack (return -1;) or not?
I have no idea what to do, but I am open for complete design revamps.
Thanks in advance.
You can use a reference counted pointer like boost::shared_ptr<> to simplify memory management. If the manager's client list uses shared_ptrs and the code that calls the callbacks creates a local copy of the shared_ptr the callback is called on, the object will stay alive until it is removed from the manager and the callback function is complete:
class EventManager {
std::vector< boost::shared_ptr<Client> > clients;
void handle_event(Event &event) {
// local |handler| pointer keeps object alive until end of function, even
// if it removes itselfe from |clients|
boost::shared_ptr<Client> handler = ...;
handler->process(event);
}
};
class Client {
void process(Event &event) {
manager->disconnect(this);
// the caller still holds a reference, so the object lives on
}
}
The Client object will automatically be deleted once the last shared_ptr to it goes out of scope, but not before. So creating a local copy of the shared_ptr before a function call makes sure the object is not deleted unexpectedly.
You should consider having an object like "Session" which will track particular message flow from start to finish (from 1 client).
This object should also take care of current state: primarily the buffers and processing.
Each event which triggers a callback MUST update the state of corresponding session.
Libevent is capable of providing you with any result of scheduled event: success, failure, timeout. Each of this types should be reflected with your logic.
In general, when working with events, consider your processing logic to be an automaton with a state.
http://en.wikipedia.org/wiki/Reactor_pattern may be a good resource for your task.
Let the Client::disconnect() function send an event to the EventManager (or Server) class. This means that you need some sort of event handling in EventManager (or Server), an event loop for instance.
My general idea is that Client::disconnect() does not disconnect the Client immediately, but only after the callback finished executing. Instead, it just posts an event to the EventManager (or Server) class.
One could argue that the Client::disconnect() method is on the wrong class. Maybe it should be Server::disconnect( Client *c ). That would be more in-line with the idea that the Server 'owns' the Client and it's the Server which disconnects Clients (and then updates some internal bookkeeping).