async await suitable to my case? - winforms

I've got a winform application, which has a database operation. Instead of the default UI blocking effect, I hope to display a special form like
System is processing. please wait
to tell users that the system is working. So basically I'm not looking for a real responsive UI. I still want to block the UI. I've achieved this goal with the backgroundworker component. Hookup the completed callback, then call the RunWorkerAsync in button click event handler, showdialog the processing form. Then in the completed callback, close the processing form.
I wonder if this scenario can be implemented with the new async/await mechanism. I doubt it.

What you call blocking the UI is not blocking the UI. Blocking the UI thread means to stall message processing so that the UI cannot change and react to input. The window usually is ghosted by Windows if this is detected.
You want to show a modal dialog. You can do that with BackgroundWorker or in a more modern way with async and await. For example:
void MyClickHandler(...) {
var form = new MyForm();
Task myAsyncOperation = StartOperationAsync(form);
form.ShowDialog();
await myAsyncOperation;
}
async Task StartOperationAsync(Form formToClose) {
await DoSomething();
formToClose.Close();
}
All of this code is multiplexed on the UI thread. Thread-safety is not a concern.

Related

Detect mobile browser close event for a mobile

I want to perform some operation when my application gets killed. Which method can be used for this? I am working on React Js.
Preventing the whole browser from being killed isn't possible, as that behaviour could easily be exploited by malicious scripts. You can, however, detect when the tab is closed.
Try the window: beforeunload event
window.addEventListener('beforeunload', function (e) {
// Cancel the event
e.preventDefault();
// Chrome requires returnValue to be set
e.returnValue = '';
});

Test fails because AngularJS has not initialized in time

I'm trying out TestCafe for an AngularJS (v1.6) application.
I have a button then when clicked, opens a modal (from UI bootstrap). This works fine when I try myself in Chrome.
<button class="btn" ng-click="open()">Open</button>
Our application requires user authentication, and the login page is not Angular-based. That phase of my test works fine.
However, when the actual test runs, it "clicks" the button but nothing happens.
I suspect, but can't prove, that it's clicked before AngularJS has properly initialized on the page.
With some research, I found the testcafe-angular-selectors project and a waitForAngular method but that appears to apply only to Angular2+.
import { Role, Selector } from 'testcafe';
const regularAccUser = Role('http://127.0.0.1:8080', async t => {
await t
.typeText('[name=username]', 'abc')
.typeText('[name=password]', '123')
.click('.btn-primary');
});
fixture`Characters Modal`;
test('modal title', async t => {
await t
.useRole(regularAccUser)
.navigateTo('http://127.0.0.1:8080/fake/page')
.click('.btn')
.expect(Selector('.modal-title').innerText).eql('Insert Symbol');
});
Adding .wait(1000) before the click solves the issue. It's not waiting for Angular to load. I'd rather not have waits in every test - is there some other technique I can use?
You can use TestCafe assertions as a mechanism to wait until an element is ready before acting on it.
A typical waiting mechanism would be:
const button = Selector('button.btn')
.with({visibilityCheck: true});
await t
.expect(button.exists) // wait until component is mounted in DOM
.ok({timeout: 10000}) // wait enough time
.hover(button) // move TestCafe cursor over the component
.expect(button.hasAttribute('disabled'))
.notOk({timeout: 10000}) // wait until the button is enabled
.click(button); // now we are sure the button is there and is clickable
This article may also help you in managing all those waiting mechanisms.
As you correctly mentioned, the waitForAngular method is intended for Angular only, not for AngularJS.
I recommend you create your own waitForAngularJS function and call it on the beforeEach hook and after the role was initialized.
In the simplest case, it can be implemented as follows:
function waitForAngularJS (t) {
await t.wait(1000);
}
fixture `App tests`
.page('page with angularjs')
.beforeEach(async t => {
await waitForAngularJS(t);
});
However, the use of the wait method is not a solid solution. I recommend you find a way to detect if AngularJS is loaded on a page on the client side. If it is possible, you can implement the waitForAngularJS method using the TestCafe ClientFunctions mechanism.
This post can be usefulĀ as well: How to check if angular is loaded correctly

Any way for React in a popup to communicate with parent window?

I've got an OAuth process that pops up a window, but when I log in, the redirect to the OAuth callback page happens within the popup rather than the parent window (window.opener). This might be a bit hacky, but I'd like a way for the popup window to tell the parent "we're authorized!"
This actually works:
OAuthCallback = React.createClass({
displayName: 'OAuthCallback',
render() {
window.opener.console.log('hello parent window');
return (
<div>
Hi, OAuth is process is done.
</div>
)
}
});
But I'm wondering if there's some way I can have the popup window tell the parent window to call a prop function, e.g. this.props.oauthSucceeded().
When you are unable to establish any parent-child or sibling relationship between the components, React recommends setting up an event system.
For communication between two components that don't have a
parent-child relationship, you can set up your own global event
system. Subscribe to events in componentDidMount(), unsubscribe in
componentWillUnmount(), and call setState() when you receive an event.
Flux pattern is one of the possible ways to arrange this.
see https://facebook.github.io/react/tips/communicate-between-components.html
Have a look at window.postMessage for cross window communication (https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
Eelke's suggestion was spot on.
I used window.postMessage() in the child window, then window.close(), then added a window.addEventListener('message', function(){}) in the componentDidMount method of of main/master component.
Check out https://facebook.github.io/react/tips/dom-event-listeners.html for more information!
I had a unique situation where I had to work on an iframed react popup from an asp.net application. I had to provide a x button to close the popup by calling a closePopup method in the parent asp.net in addition to other ways to close it. I used window.parent. Below is how I used it.
if (window && window.parent) {
window.parent.closePopup();
}

Confirm box is blocking/pausing

I have a ng-click="myFunc(aEntry)"
And then myFunc is this:
MODULE.myFunc = function(aEntry) {
aEntry.hilite = true;
if (!confirm('Are you sure?')) {
aEntry.hilite = false;
return;
}
};
However it wont update the dom to show it highlighted. The confirm box seems to be pausing it. Does anyone know a work around?
It is because confirm is a blocking function. I understand you want to have a ui change, but
aEntry.hilite = true;
is not a UI change. It is a logical change. You probably have an event handler which runs after you have called confirm. You need to guarantee that the highlighting ui operation is performed before you call the confirm. There are several ways to do it.
The most primitive way is to use setTimeout and put your confirm call inside it, using a time, which is surely longer than the time you need to wait for the ui handler to be executed.
A slightly better approach is to use setInterval until the ui change has occured.
But the best approach would be to pass the confirm with a function wrapped around it used as a callback for the ui change or to trigger the ui change event before you call confirm.

Silverlight: stop thread while waiting for user feedback

Is it OK to stop current thread until user click some buttons in Silverlight? E.g.
var clicked = false;
ShowDialog(EventOnClosed => clicked = true);
while (!clicked) {};
return;
P.S. I know the right way. I'm just curious if there's a way to stop and then continue Silverlight execution flow.
P.P.S. Just to be more specific. Imagine a project where javascript alert() is used for messages. How do you replace "return Invoke("alert('')")" with Silverlight messageboxes? Do you change all 500 places to use the correct async technique?
No it isn't and you certainly won't want to tie up the CPU like that even if you do.
In Silverlight you really need to get used to programming in an asynchronous way.
void SomeContainingFunc(Action callBack)
{
ShowDialog(EventOnClosed => callBack()))
}
Whatever calls that and wants code to continue after the async operation is completed:-
void SomeCaller()
{
// ... do some intial stuff here
Action callBack = () =>
{
//.. code to happen after async call completed
}
SomeContainingFunc(callBack);
}
What you are attempting to do is halt (or more specifically pause) the UI thread - this is not a good idea in any circumstance, especially if you are waiting for the user to click something!
Just do it the "right way".

Resources