Wait for something of variable time to complete before continuing method - objective-c

I need to be able to halt a method while it waits for user input.
I tried using a while (true) loop to check to see if a boolean was set indicating that the operation had completed, but as I predicted, it made the application non-responsive.
How do you halt and resume a method after a variable has been set, without calling the method again, and without making the entire application non-responsive.
Here's basically what the program does
openFile method called
openFile method determines whether file has a password
if it does, display an alert to the user requesting the password
Here's the problem, halting the method until the password has been entered.
Any help appreciated.

Why do you want to halt the method? You could use a delegate. You present the alert view and register the delegate for the alert view. The delegate registers for the didDismissAlertViewWithButtonIndex method and acts according to the button. If the password was entered correctly and the OKAY button was tapped, you can continue with your process.

You can't. You need to split it up into two methods, one that does the initial check and then prompts for the password, then the second that uses the password to get the file.

You may need something like below.
class Program
{
static void Main(string[] args)
{
}
void YourFileReadMethod()
{
string password = string.Empty;
bool isPasswordProtected = CheckFileIsPasswordProtected();
if (isPasswordProtected)
{
Form passwordFrm = new Form();//This is your password dialogue
DialogResult hasEntered = DialogResult.No;
do
{
hasEntered = passwordFrm.ShowDialog();
password = (hasEntered == DialogResult.Yes) ?
passwordFrm.passwordTxt//password property/control value;
: string.Empty;
} while (hasEntered != DialogResult.Yes);
}
ReadFileMethod(password);
}
private void ReadFileMethod(string password)
{
//use the password value to open file if not String.Empty
}
bool CheckFileIsPasswordProtected()
{
//your logic which decides whether the file is password protected or not
//return true if password is required to open the file
return true;
}
}

Related

How to modify a form in a background thread

This might be a simple question but I can't figure it out.
I have a form called in my main function:
void Main() {
Mem = new MemoryManager();
Console::WriteLine("Thread Started");
Application::EnableVisualStyles();
Application::SetCompatibleTextRenderingDefault(false);
FinalSolution::ControlPanel form;
Thread^ cLoop = gcnew Thread(gcnew ThreadStart(loop));
cLoop->Start();
Application::Run(%form);
}
All I want to do is, if someone presses a key in general (not just when the program is in focus), it changes the background to a different color.
I have tried a few things but nothing has worked so far. Here is the loop and I have indicated where I want it to happen.
void loop() {
while (true) {
if (GetAsyncKeyState(key)) {
//Here
form.button->BackColor = System::Drawing::Color::ForestGreen;
}
}
}
Of course the issue is that this function doesn't know what form is, but I don't know how to tell it.
Ended up just putting the loop directly in the form header and that solved the problem.

Program doesn't wait for modal dialog

With this program I am attempting to have the user select a text file that is a representation of a 4x4 sudoku problem. My agent will then take this file and attempt to solve the sudoku puzzle.
The problem I'm running into is that I can't seem to figure out how to get the proper file selected, and then passed into the method call for processing.
This is the file selector class I've created. So far it successfully brings up a button, and when clicked brings up the computer's file structure so the user can select a file.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
/**
* Created by neil on 7/12/17.
*/
public class file_selector {
public JPanel panel1;
public File file;
JButton button1;
public file_selector() {
final JFileChooser fc = new JFileChooser();
button1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int returnVal = fc.showOpenDialog(null);
if (returnVal == JFileChooser.APPROVE_OPTION) {
file = fc.getSelectedFile();
System.out.println("You chose to open " + file.getName());
}
}
});
}
public File getFile() {
return file;
}
}
This is my main method in which I attempt to use the file that the user selected. When I put the function calls in a while loop (like it is currently) it never proceeds because the file is never set. If I don't put the function calls in a while loop, I get a nullPointerException error when I try to process the file because the file has a null value.
public class sudoku {
//create 2d array that represents the 16x16 world
public cell[][] world_array = new cell[15][15];
static File myFile;
ArrayList<String> world_constraints;
public static void main(String[] args) throws IOException {
JFrame frame = new JFrame("file_selector");
file_selector fs = new file_selector();
frame.setContentPane(fs.panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
myFile = fs.getFile();
while(myFile != null) {
sudoku my_puzzle = new sudoku();
my_puzzle.solve_puzzle();
}
}
I've done a ton of searching and can't seem to find what's wrong with my file_selector class such that it isn't setting the user selected value for the file.
You call getFile immediately after showing the frame and before the user has opportunity to click anything. Since the condition for while is false, the loop ends immediately and the method doesn't do anything afterwards, in particular it never calls getFile again.
Two options:
Make the button solve the puzzle, not just set file (easier, just change actionPerformed method).
Make file_selector emit an event when a file is selected and add a listener to it (this can be a challenge for you).

static method in react native bug(callback)

I will try my best to explain the problem i have.
here is a sample code
auth.js
static authenticate(email,password,callbackIsLogged)
{
//some logic
if(passwordCorrect)
{
callbackIsLogged(true);
}
else
{
callbackIsLogged(false);
}
}
login.js
loginButtonClicked()
{
Authcontroller.authenticate(email,password,function(loginState)
{
if(loginState)
{
alert('correect');
//proceed withlogin.
}
else
{
alert('error');
}
});
}
the problem i have is weired.
lets look at a sample scenario where this bug happens.
if i login with correct username and password for the first time when the app opens everything goes according to plan.
But if i enter the incorrect password at the first time and the second time enter the correct password the callback function will get called twice with boolean value true and false.
It seems like the static function somehow hold the previous callbacks and execute them.
hope you undestood my question. how to fix this.
thanks.

Flow of initializing objects in XAML?

I'm not sure but from my hours of debugging, this should be the best description of my problem I can give.
I'm creating a WinRT app, there are two pages- Main Page and Details Page. Inside Main Page constructor, I have initialized a listbox. On click of any of the element of listbox, user is taken to the Details page.
I'm just learning all this and design may not be best but here is what I did.
I took a static variable in MainPage.cs, and set it to point to the element which is clicked by the user. Now in the constructor of the Details page, I used this static variable to set the datacontext of Details Page itself.
What flow I'm expecting is:-
MainPage is created first. Listbox is setup.
User will click on any of the element of listbox. Itemclick event handler runs. It will set the static variable (of Mainpage.cs) to hold the infomation which item is clicked and navigate user to the Details page.
In Details page constructor, I have set the datacontext to point to some information based on the value of static variable mentioned in the previous step.
It works for most of the times, but once in like every 5 times, The Details page constructor throws an exception stating the static variable is not initialized yet. Why is Details page's constructor running when I'm starting the app? and why only sometimes? Do I need to set DataContext of Details Page in some other method instead of constructor?
The code is somewhat complex and too much in terms of domain of the problem so I'm avoiding posting it. But if I'm failing to explain the problem please tell, I'll post it keeping it as related as I can.
CODE:-
This is the method called when an item in listbox is clicked--will take user to the Details page.
private void overviewlistbox_Tapped_1(object sender, TappedRoutedEventArgs e)
{
MatchOverview selectedmatch = (sender as ListBox).SelectedItem as MatchOverview;
matchFullDetails = new ObservableCollection<Match>();
foreach (Match m in UpdateController.matchList)
{
if (m.matchDescription == selectedmatch.matchDesc)
{
matchFullDetails.Add(m);
break;
}
}
if(!(matchFullDetails.Count == 0))
this.Frame.Navigate(typeof(Details));
}
This is the constructor for Main Page:-
public static ObservableCollection<Match> matchFullDetails;
public MainPage()
{
matchFullDetails = new ObservableCollection<Match>();
this.InitializeComponent();
UpdateController update = new UpdateController(); // Creating new object will update the overview_list of UpdateController(static list).
overviewlistbox.ItemsSource = UpdateController.overview_list;
}
And this is the code for constructor of details page, where the exception occurs:-
public static ObservableCollection<Match> matchdetails = new ObservableCollection<Match>();
DispatcherTimer dtm_detailspage = null;
public Details()
{
this.InitializeComponent();
matchdetails = MainPage.matchFullDetails; // matchdetails.Last<>() is take because we only need item which is added latest to the collection.
if (matchdetails.Last<Match>().type == "TEST") // Exception is thrown here--Initialization
// error. When I check MainPage.matchFullDetails,
// no data is shown which means its not yet
// initialized. Also the exception is thrown either at
// the start of the app, or when details page is visited. That too once in 4-5 times, not always.
{
matchdetails.Add(matchdetails.First<Match>() as TestMatch);
}
if (matchdetails.Last<Match>().type == "ODI")
{
matchdetails.Add(matchdetails.Last<Match>() as ODIMatch);
}
if (matchdetails.Last<Match>().type == "T20")
{
matchdetails.Add(matchdetails.Last<Match>() as T20Match);
}
}
Exception Screenshot:-
Call Stack data on bug encounter:-
[Cricket Expert.exe!Cricket_Expert.Details.Details() Line 33 + 0x5 bytes
[External Code]
Cricket Expert.exe!Cricket_Expert.Common.SuspensionManager.RestoreFrameNavigationState(Windows.UI.Xaml.Controls.Frame frame) Line 236 + 0x5 bytes
Cricket Expert.exe!Cricket_Expert.Common.SuspensionManager.RestoreAsyn() Line 124 0x8 bytes
Cricket Expert.exe!Cricket_Expert.App.OnLaunched(Windows.ApplicationModel.Activation.LaunchActivatedEventArgs args) Line 74 + 0x5 bytes
[External Code]
MAJOR UPDATE:
I finally found the flaw. If the Details page is still active, and the app is restarted, the problem occurs.
Is there a solution to this problem??
You can pass information on what needs to be displayed on the Details page through the Navigate call and set the DataContext in OnNavigatedTo override to avoid using static variables. Pages don't get created unless you do it specifically e.g. by navigating to one. They might not be recreated if a page has NavigationCacheMode changed from the default (Disabled) so instances of the page can be reused during navigation calls. Ultimately it's hard to say what's wrong but it seems like something in your code and we couldn't help you if you don't share a sample that reproduces the problem.
*EDIT
One way to debug Details being created before MainPage would be to add this code at the beginning of the Details constructor:
if (MainPage.matchFullDetails == null)
{
System.Diagnostics.Debugger.Break();
}
Then look at the Call Stack panel in Visual Studio to see how it gets constructed.
One way to see if matchFullDetails is ever set to null is to search for its assignment (put a cursor on matchFullDetails in Visual Studio code editor and hit Shift+F12).
Another way would be to make matchFullDetails into a property and test it like this:
private static ObservableCollection<Match> _matchFullDetails;
public static ObservableCollection<Match> matchFullDetails
{
get
{
return _matchFullDetails;
}
set
{
if (value == null)
{
System.Diagnostics.Debugger.Break();
}
_matchFullDetails = value;
}
}
*EDIT 2
You can initialize your static property in a static constructor like this:
public static ObservableCollection<Match> matchFullDetails;
static MainPage()
{
matchFullDetails = new ObservableCollection<Match>();
}
public MainPage()
{
this.InitializeComponent();
UpdateController update = new UpdateController(); // Creating new object will update the overview_list of UpdateController(static list).
overviewlistbox.ItemsSource = UpdateController.overview_list;
}
this will prevent the null reference exception but won't fix your problem overall. When your app gets suspended and resumed - you have to restore the full state and it seems like your matchFullDetails collection would need to be serialized and saved to disk when your app gets suspended. Alternatively you might simply ignore the suspension manager call in App.xaml.cs and always start on home page, though that's not a very good experience and I am not sure if it satisfies app certification.

Silverlight 4 Asynchronous Issue

I am creating an application in Silverlight 4. The first screen the user comes in contact with is the Login screen (Login.xaml). I have written the following code in Login.xaml.cs file.
private void btnSubmit_Click(object sender, RoutedEventArgs e)
{
//first validate if the user is authorised for this application
if (this.ValidateEntry())
{
if (UserAuthenticationBL.AuthenticateUser(txtUserName.Text.Trim(), txtPassword.Password.Trim()))
{
//since the user is authenticated we will show the dashboard screen
this.Content = new MainPage();
}
else
{
this.ShowErrorMessage("Invalid username or password");
txtUserName.Focus();
}
}
}
My problem is that the code gets executed before i get the data in the AuthenticateUser method. The code immediately comes down to the "Invalid username or password" and the list is loaded after all the execution on the xaml page has finished.
I know there is something going wrong with the Asynchronous thingi...and i also know i need to put an event to know when the loading has completed........
but i dont know how to go about it!!!
can someone please put some light on this issue...
thank you.
If I understood it right, your AuthenticateUser method is running async, right?
You have to define a callback to the AuthenticateUserComplete event and run the method in the button submit event. In the callback write this if/else clause, then it will be called once the asynchronous method was completed.
Just one question, why are you doing asynchronously if your behavior should be synchronous? (You have to get the answer before deciding what to do).
This http://msdn.microsoft.com/en-us/library/aa719598%28VS.71%29.aspx
may be helpful :)
Oscar