How to handle incoming ajax requests after destroying window? - extjs

I create a window containing grids that send off ajax requests. Now, I immediatley close the window again before the grids are fully created and the ajax requests return.
I have two problems:
My components within a window are still "alive" after a window is destroyed
Chrome console lists them. Although my window has the autoDestroy: true the gridpanel and store are still existing after the window is closed. When closed, the destroy event is fired. Docs say, all components under the window should be destroyed.
Then my callbacks finally return and get executed but the window is destroyed
The problem is, that the callbacks try to reconfigure a grid that has no more store attached.
Error: Uncaught TypeError: Cannot call method 'getCount' of null Table.js:500 (/lib/extjs/src/view/Table.js
How can I stop the callbacks from processing if my window is destroyed?

Registering the events with mon so that they get removed when the listening object get destroyed. Alternatively you may:
remove them manually within the destroy() method
check within the callback for methods or properties that may not exist to skip them
Edit
There are some more things that you can do
check if the destroy() methods of the grids get called
abort all request by calling Ext.Ajax.abortAll() (before the window close)
abort just specific requestst by calling Ext.Ajax.abort(request) (before the window close)
I recommend to use option 2. because it should be the safest.
Edit 2
To take a look at all running request you need to look at the private requests property of Ext.data.Connection from which Ext.Ajax extend. requests is of type object and will contain a property (the request Id) for each request that is currently running.

Related

Serious memory leak/zombie event handlers when using `Backbone.history.loadUrl`

In an application, Backbone.history.loadUrl() is used to load a page. But I find that events in a view is not unbound, thus creating more and more zombie events when it is used to load a page. Whats the right way of loading a page. (changing URL and probably calling close() on active views to trigger any cleanup if necessary.
... actually the answer is simple ... I just need to call .close() where necessary. In my case:
#contentView.close()
Backbone.history.loadUrl Backbone.history.fragment

Detecting async function calls completion in silverlight

Say,there is a requirement that a customer object is loaded from the db to a silverlight application, so that the customer details are shown in the UI. We need to detect if the user is changing any data in the UI.
We are listening to property changed notifications from the view model. However, when the notifications are result of property change as part of the loading process we have to discard it.
class CustomerLoader
{
Helper helerobj;
Address addressobj;
Profile profileobj;
void LoadFromDb()
{
helperobj.Load();
addressobj.Load();
profileobj.Load();
//start listening after the loading finished
this.propertychanged += new PropertyChangedEventHandler(handlepropertychanged);
}
The trouble with this is the inner objects might be calling asynchronous functions which might set properties. So by the time we started the property change listening, the loading might not have been finished.
We need to know when the loading is actually done. As of now we are asking the developers who are developing the inner object classes to accept a callback in the parameter which they should call when the function is finished.
Is there any other way to do it?
You want nothing but a really classic asynchronous objet loading.
So yes, the only solution is to ask developers working on the loading to propose an asynchronous function. Now you hav several solution to achieve asynchronicity in Silverlight.
You could either provide a callback as you do, or use async and await to manage your asynch task as explain here: http://10rem.net/blog/2012/05/22/using-async-and-await-in-silverlight-5-and-net-4-in-visual-studio-11-with-the-async-targeting-pack

Sencha Touch store 'aftersync'-like event

I'm using a ListView with a store/ajax-proxy/json-reader/json-writer. I'd like to set the ListView to loading before I call store.sync(), and remove the loading once the response got back from the server.
Problem is, I don't know where I could hook in my call to be processed once the request is done, as all I'm doing is calling sync().
Store has a beforesync event, what I'd like is something like aftersync. Any ideas how to accomplish that?
By reading the Sencha Touch source code, it turns out that the afterRequest function is called just after the request is finished. This config option can be passed to any Ext.data.Proxy subclass. The two arguments passed are request and success.
Interesting though that it's not present in the API docs.

WPF: how to marshall data to user control from another domain

I have to use functionality that is in another application domain. The result should be displayed in user control.
I have something like that:
var instance = domain.CreateInstanceFromAndUnwrap(...);
instance.Foo(myWpfUserControl as ICallback);
Foo(ICallback itf) {
itf.SetData("...");
}
WpfUserControl.SetData(string data)
{
if (!Dispatcher.CheckAccess())
Dispatcher.Invoke(...)
...
}
I had to put [Serializable] attribute onto WpfUserControll class and implement serialization contructor as well as ISerializable interface but now i receive exception:
The calling thread must be STA because many UI components require this
that is raised from UserControl() constructor
What shall I do to avoid this ?
Thank you in advance !
==============================
Solution
as #Al noticed, my user control have to be serialized when it comes to cross-application-domain calls. Now i pass proxy, that implements ICallback interface. Proxy was marked with Serializable attribute.
Proxy implementation should have absolutely no knowledge about user control as there should be an attempt to deserialize user control instance once again. When I tried to abstract proxy from user control via interface it didn't help. When i tried to pass interface to proxy (that was implemented by user control) - same exception occured.
Finally I decoupled proxy and user control with queue/semaphor. Queue was monitored by a worker thread that deligated calls to user control
p.s. this queue should be inherited from "MarshalByObjectRef".
If the exception is coming from the constructor, it means that you're not creating this control instance from the UI thread. This can be fine but you have to make sure the Thread is an STA thread by calling .SetApartmentState(ApartmentState.STA) on the thread object before the thread is started.
This also means you have to have access to the thread object before its started so you cant do this on a threadpool thread.
The best way to avoid the problem though is probably to create the control on the main UI thread and then assign the Text value using the Dispatcher (or a Task on the UiScheduler). That way you'll also avoid problems if the main thread needs to set, get or bind to the control, as that would cause a cross thread exception if the control was created on another thread
i'd advice against seriealizing the control this way if possible. doing that will generate a new object that is not attatched to any panels or some such, and the original control would not be updated. sadly you cant inheirit from MarshalByRefObject that would eliminate serialization since it would only pass a reference to the other domain.
If you can, call Foo separately and then pass the result to SetData in the original Appdomain

WPF access GUI from other thread

I am working through the requirement to make a WPF Application single instance only.
However - I have to pass the command line to the first instance and then perform some UI action.
I am using a Mutext to check for already running instances, I do use NamedPipes to transfer the command line to the already running instance.
But of course I am not in the correct Thread to access "Window1".
I tried to store a reference to "Window1" in a static class and then use the Dispatcher to call a Method in "Window1", however, as soon as I try to access a variable (class wide scope in "Window1") I receive a "Object reference not set to an instance of an object."
The UI Action is to add a new Tab to a TabControl - during initialization of the new Tab some work is done - and the variables are initialized and even the method I want to call works during the init - but when called from the Dispatcher it fails.
Any hints, how to do this? Am I on the wrong track here?
Thanks!
This is easy:
void ProcessCommandLine(string commandLine)
{
Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.ApplicationIdle, new Action(() =>
{
... code to process the command line here ...
});
}
You can call this from your App.Startup and also from your thread that receives messages from the named pipe.
The key considerations here are:
Use of BeginInvoke instead of Invoke to prevent the calling thread from waiting
Use of DispatcherPriority.ApplicationIdle to guarantee the application has finished initializing before the command line is processed
Use of Application.Current.Dispatcher instead of Window1.Dispatcher in case Window1 has not yet been initialzed
That's not right, are you certain that the mutex is passing control correctly to your currently running instance of the application?
If it was a thread UI access issue, you should have received this error: The calling thread cannot access this object because a different thread owns it.
The fact that you're getting an "Object reference not set to an instance of an object." error message means that you've not yet instantiated the object as new.

Resources