My windows 10 IOT core application uses SPI to collect change notifications of
many entities. There are excellent examples for launching a timer to get SPI data, update data and binding UI elements to this data. The result is anytime SPI gets some data about a changed entity, the data that drives the UI is updated and any UI element bound to this data is updated. I can even change what subset of data is displayed on this page by using two way bindings to track the selected items on a list.
Just like the many examples, my code is structured as follows:
public async void Init_SPI()
{
....
periodicTimer = new Timer(this.TimerCallback, null, 0, 10);
} // public async void Init_SPI()
private void TimerCallback(object state)
{
/* UI updates must be invoked on the UI thread */
var task =
this.Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, () =>
{ ... update states of data that many be bound to UI element
My issue / question:
I don't see how to update data for multiple pages based on the above, since this.variable refers to the UI thread of the page that launched the timer.
It would be too inefficient to update a static class and have the multiple pages continuously poll this static data to make the UI track these large number of element.
My only thought at present is to code all the XAML pages in one page and tab between these "virtual" pages. I would rather have multiple pages to keep the functionality of these pages separated.
Any suggestions for how I could update multiple pages from data read on a SPI port would be appreciated.
Regards,
John
Sorry for a very late answer, but my solution would be to still create "real" pages -- but "relayed" the data only to the currently visible page. So whenever a page becomes visible I would have made the internals of the code piece above { ... update states of data [...] to point out that page.
This could be achieved with a simple switch statement, or by a simple interface with a HandleSpiData(TheSpiData) method -- or even a simple Action<YourSpiData>.
Related
I'm doing some kind of social, it's when i open a post a new scene is created which initializes the elements with the data taken from the database. the problem is that the big photos take time to load, and until they load the program does not respond, I would like a way to be able to open the scene first so as to wait until the image loads without the program crashing
public void init(int idpost) throws SQLException {
this.post = new PostDAOImpl().getPost(idpost);
photo.fitWidthProperty().bind(imgContainer.widthProperty());
photo.fitHeightProperty().bind(imgContainer.heightProperty());
photo.setImage(new Image(post.getPhoto()));
name.setText(post.getProfile().getName());
username.setText("#" + post.getProfile().getUsername());
if (post.getProfile().getAvatar() != null)
avatar.setImage(new Image(post.getProfile().getAvatar()));
description.setText(post.getDescription());
}
here is the code, which is executed as soon as the scene loads. I was thinking of doing another DAO to first fetch all the data except the photo, load the scene and only then fetch the image or something like that, but I don't know how to do it
I think it is always a good idea to create and show a GUI in the empty state quickly first and then launch some background task to collect the data and once this data is available update the GUI. Just think of a word-processor GUI. When you launch it it's in the empty state without any document. Then the user selects a document which gets loaded and as soon as the data is available the GUI changes and displays the document. The only difference in your case is that you already know which data you want to load.
I am creating a winRt app. In which I am having a Home.xaml page which having a another page called Market.xaml. So for snapped mode the same code is repeated.
Now my itemListView (used for snapped) and itemGridView (for full view) both have this page (Market)
<views:Market x:Name="viewMarket"/>
And the constructor of this page is called twice which I not want.
So do I use some flag kind of thing or some better approach is there.
Thanks
So, let's talk about this:
XAML is basically a varying syntax to C#. So, when XAML references a control like your views:Market with <Views:Market />, you are actually putting in something like new Views.Market() in both places. Basically, invoking the class twice. Should the constructor not fire twice, the time-space continuum would split in half. Dogs and cats living together, the whole 9 yards.
But, more fundamental here, what is the purpose of the constructor in C#, or in a XAML class? Is to do expensive things that you would not want to repeat? No. The reason for this is because the completion of the constructor is necessary before the UI thread is released and allowed to render the control. The resulting effect is a UI hang.
Moreover, the C# constructor is a synchronous method. It cannot properly invoke or hold asynchronous operations. This means long-running or expensive tasks that should be invoked immediately, should not be invoked in the constructor because it would also require them to be synchronous and UI-blocking. It is because of these last two points I suspect your constructor is being misused.
The solution is in the XAML framework. The XAML Page pipeline includes the constructor (since it is a C# class and they all have it) but it also includes a Loaded event. In many cases, the hard work necessary to fill page controls is in the Loaded handler. This allows the page to render properly, then starts the long-running action that will ultimately and asynchronously update control content.
In WinRT, the Page pipeline also includes an OnNavigatedTo() virtual method in the base that you can override to the same effect. In the override you can include the hard work of talking to a service, deserializing from a file, or whatever you need to make your UI work. Both the Loaded event and the override can be asynchronous, and neither prevent rendering by freezing the constructor.
But, there's another thing to consider since we're in C# and that the rather common pattern called singleton that allows for us to reference a type in two different contexts but without creating a brand new class. This is accomplished by making the class constructor private, but exposing a public property usually called Instance that returns a single, shared instances in some static place.
That might solve your problem already. Then again, none of that is probably what you need. Assuming you already know all that, the quick answer is you can't prevent a constructor because a constructor is necessary to create a new instantiation of any class, including a XAML view. Instead, whatever you are trying to prevent being double might need to be a combination of the discussions above. An offloaded method, and a static reference to prevent duplicate efforts.
Something like this:
public class Market : UserControl
{
public Market()
{
Loaded += Market_Loaded;
}
static bool AlreadyLoaded = false;
void Market_Loaded(object sender, RoutedEventArgs e)
{
if (AlreadyLoaded)
return;
AlreadyLoaded = true;
// TODO: your work
}
}
But that might not do it for you because the static variable is scoped too large. Instead, you can control if it does the big operation with a dependency property you add to your control. With a boolean dependency property set to false, the second control knows not to do something. With it set to true, the first knows to go ahead. And, so on. This prevents all future use of the view or user control in your app from thinking it should not run because of the static property in the above solution. Then again, that might be perfect.
Best of luck!
Use Case: User logged in and a Vaadin Table component opened showing statuses of appointments. Every row has a drop down (ComboBox) to change status (Scheduled, Arrived, Reviewed). Now multiple users has opened this table in their own browsers and making continuous changes to appointment status. These changes should be reflected on all opened tables i.e if user A changes status of appointment appt-1 it reflects and refresh on all Tables currently opened.
Previously we applied event based refreshing with ICE-PUSH Add-on i.e if Change made on PC-1 (i.e Application instance a1), i get the other instances of Vaadin application from static CopyOnWriteArrayList from MainApplication class and by that instance I call loadTable function. after that I call the ICEPUSH to push new changes to all users.
public class MainApplication extends Application {
public static CopyOnWriteArrayList<MainMedMaxApplication> appList=new CopyOnWriteArrayList<MainMedMaxApplication>();
#Override
public void init() {
setMainWindow(new Window("APPointment Dashboard"));
getMainWindow().setContent(mainLayout);
setMainComponent(getCustomTable());
//Custome Table make table . it also register listeners over table.
//loadTable will load the table.
loadTable()
appList.add(this);
}
}
public void loadTabl(String date) {
//this will reload the table component By Querying database
}
private void registerlistener() {
table.addListeners()
{
//do any change to table in this instance and save it to db then call ICE push so it can referesh all app instances by getting from applist.
synchronizePortlets();
}
}
public void synchronizePortlets() {
// TODO Auto-generated method stub
Iterator<MainApplication>itM = appList.iterator();
while(itM.hasNext()) {
MainApplication app = itM.next();
app.loadTabl();
app.getPusher().push();
}
}
}
This works fine but in some conditions when to many frequent changes made then Concurrent Modification Exception rises. so if any one can help to improve this?
The solution I am thinking after this is to refresh table component not forcefully rather continuously in every 1 mint by its own app instances. This will query database and reload the table container with updated statuses. For this purpose I use Refresher add-on But it raises an exception i.e ConcurrentModificationException, because sometimes user also changing the table component by changing combo statuses in table meanwhile refresher refresh the Table and here raises concurrent Modification exception. So I am thinking of freezing Table component from user point of view so user can't do anything and in background can easily refresh table.
If for this use case you guys have better solution please do tell me. I am grateful of you.
Using Vaadin 6.8.12, java 1.7, apache Tomcat 7.42
Vaadin 6
You need to apply synchronization since you're making changes to the GUI from another thread (and I think it doesn't matter whether Refresher or IcePush is used, I think in both cases you'll use another thread). Synchronize on the Application instance.
See this post on the Vaadin forum.
Vaadin 7
EDIT: I encourage you to upgrade to Vaadin 7.1 and use this new method on UI: UI#access as is recommended here.
I have implemented MVP pattern in my GXT project. The system registers customers as part of it function. Also the system user can search for the registered user providing the id.
i have added an OnClick event to the "search customer" button.
/* On click search button */
view.getBtnSearch().addListener(Events.OnClick, new Listener<BaseEvent>() {
#Override
public void handleEvent(BaseEvent be) {
eventBus.fireEvent(new CustomerRegistrationTabSelectionEvent(0, false));
eventBus.fireEvent(new CustomerFetchEvent(view.getValueCustSearchParameter(), view.getValueCustSearchValue(), true));
}
});
The CustomerRegistrationTabSelectionEvent does select the relevant tab and enables other tabs. Thats all it does.
Here is the handler for the custom event CustomerFetchEvent.
eventBus.addHandler(CustomerFetchEvent.TYPE, new CustomerFetchEventHandler() {
#Override
public void fetchCustomer(CustomerFetchEvent event) {
searchCustomer(event.getParameter(), event.getParameterValue(), event.isOpenFirstTab());
}
});
The issue is the search customer method is executed multiple times and if there is a invalid search the error message dialog shows multiple popups. Within the searchCustomer method i call for service which fetch me the customer data or show the popup error message if the search is invalid.
im using GXT 2.2.5 and JRE 1.6.
Could anyone help me in finding out why the code is executed multiple times?
Added Later:
When i run the application first time the code is only executed only once, therefore only 1 popup. Then i logout of the system and log in again (navigating to the same page where the "search customer" button exists.) and the code is executed twice. Likewise equal to the number of times i create/navigate to the particular page, the code executes. Is it actually adding the event handler code without removing the last one every time i recreate the page?
Yes, it seems that 'addHandler' adds handler multiple times, but stores previous context. Your code should add handlers only once, on initialization phase. You can check the number of handlers with 'getHandlerCount' method.
Ya. I fixed it!Here is the solution Unbinding presenters necessary in GWT
U can read more here. http://draconianoverlord.com/2010/11/23/gwt-handlers.html
what happened actually was, the presenter objects where i have registered with HandlerManager to receive events were not garbage collected. Because though i remove the reference to the presenters still the HandlerManager holds a reference to those objects. So every time i kept on creating new presenters on top of the old presenters of the same class. so a event is listened by multiple objects of the same class. so u need to ensure that the unused presenters are garbage collected by removing the registered handlers
in HandlerManager.
I have an application that requires to use QWebView::setContent() to load some HTML content to a QWebView. All of this happens on an embedded device with ARMv5 processor (think 400 MHz). Most of the time, I can load the page in reasonable time (up to 5 seconds), however sometimes I have content that takes long time to load (~30 seconds for 300KB of content).
The problem is that the setContent call blocks the main thread. I need to be able to process events during the loading, and maybe even cancel the load if the user decides not to wait any longer.
I was thinking about running the setContent call in other thread, so that it does not block the event processing and I can cancel it if necessary. However, I get the dreaded "widgets must be created in the GUI thread", and I see no way of solving this easily.
Is it possible to run QWebView::setContent in a separate thread? If so, how? If not, is it possible to handle GUI events while setContent is running? Is it possible to "cancel" the setContent call?
EDIT
To clarify a bit more, what really interests me is how to be able to stop the setContent call and/or handle GUI messages, so that the interface remains responsive, with large amounts of data passed using setContent.
EDIT 2
To clarify even further, I am dealing with long, static content, i.e. no JavaScript, just a lot of static HTML, through which the user wants to scroll even while it is loading more content. The main idea is to allow her/him to go down a page even when the page is not fully loaded.
Some time ago I faced a similar problem. As far as I know, only the main contents of the page is acting synchronously.
The fact is that the GUI core "paints" the page and this is time consuming. So, the main thread gets freezed until the main contents is loaded completely.
In my case, the solution was simple: make the main contents a secondary one and work with local files!!!
So, what is my proposal:
1) Prepare a local file (/tmp/loader.html) that contains something like this:
<html>
<body onload='setTimeout(function() { window.location="contents.html"; }, 1000);'>
Loading...
</body>
</html>
2) Each time you need to load a new content, save it to the secondary file (/tmp/contents.html) and force the update of the loader (maybe also a refresh). Easy:
QFile f("/tmp/contents.html");
if (f.open(QFile::WriteOnly)) {
qint64 pos = 0;
while (pos < contents.length()) {
pos += f.write(contents.mid(pos, 1024)); // chunk of 1024
qApp->processEvents();
}
f.close();
webview->setUrl(QUrl::fromLocalFile("/tmp/loader.html"));
}
Observe that I permit the event loop to process pending events if the file saving is also slow...
3) Anytime you need to cancel the loading, you can load another contents, remove the contents file, or other possible approaches.
Note that, as far as I know, you would never make asynchronous the painting of the contents. And that is the real issue in embedded systems.
Since QWebView::setContent() is a blocking call, I ended up using a work-around. The main idea is that XML processing is much faster than rendering the page. Therefore I do the following:
Parse the document as XML DOM document (a reasonable assumption in my case), and find the body element.
Keep only a pre-defined number of child elements of body (something like 20 elements). Store the remaining elements in another XML DOM document.
Show the initial document (serialized XML) using QWebView::setContent(), which is relatively fast. Start a timer with timeout 0 on SLOT(loadNextChunk()).
loadNextChunk() moves another 20 or so elements from the backup document at the end of the body using body->appendInside(html), where body is a QWebElement.
Stop when no more elements are available.
This works because in between the calls to loadNextChunk(), the GUI has a chance to react to events.
QWebView, as its name suggests, is a widget. QWebPage, on the other hand, is a plain old QObject, with all the threading goodness you could possibly want.
Now tie it together:
void QWebView::setPage ( QWebPage * page )