I am trying to fill a form which sometimes needs some waiting periods , so after a lot of search I was able to delay the execution of some commands (I had to create a separate thread to do that) and it worked fine but when I try to use commands from the WebEngine such as executescript it does not work.
here is my snippet :
Note: eng is a WebEngine instance and it is working fine outside the thread.
Update: After a small test I found out that the eng instance is working fine in the thread but I can not run eng.executescript()
Update2: after some search I found out that the eng.executescript has to run on the main thread , but in the same time I need to delay the execution for some time I'm not sure how I can do it.
Thread one = new Thread() {
public void run() {
try {
System.out.println("Does it work?");
Thread.sleep(2000);
eng.executeScript("document.getElementById(\"textFieldId\").value = 100");
System.out.println("yup");
} catch(InterruptedException v) {
System.out.println(v);
}
}
};
one.start();
I have resolved the issue by implementing the waiting part by the javascript using setTimeout function , and it worked as a charm
Related
I have a Kotlin function that will take a while, and will then return a result (It downloads and parses a file).
I run it from Flutter like this:
void click() {
platform.invokeMethod('runMyLongFunc').then((a) {
print("Done");
setState(() {});
});
}
What should I do for this to run in a background thread (as of now it's blocking on the UI thread).
I tried making click async and it didn't help (void click() async).
There are a couple things you could try.
One is to have the Kotlin function do its work in a background thread using one of the methods Android offers for that (AsyncTask, for example). You could use a MethodChannel to handle the communication between the JVM and Dart, and have the Kotlin code send a message when it was done.
Another possibility is to use a Dart Isolate to multithread on the Dart side. You'd create an Isolate, make the call to Kotlin in its run method, and your other dart code could asynchronously wait for it to be finished on the UI thread while still running the event queue. The Flutter team has an example of how that might work.
void click() async{
var a = await platform.invokeMethod('runMyLongFunc');
print("Done");
setState(() {});
}
the await there is the key. Although it still runs on the single thread.
I am trying to make a stopwatch in Xamarin Forms and was wondering if I should use the native UI threading or Parallel Task Lib to constantly update the time label?
I tried to use the PT Lib, but I'm unable to get it to update my label, which makes me think that I should be using Native Threading, but I'm worry if I would be able to update the UI using a dependency service.
Is there a best practice for constantly updating the UI but still being able to execute other tasks such as button clicks?
UPDATE: I got this code below to work, but is this good practice? I am updating the time label constantly while still also bing able to press the lap buttons.
Stopwatch sw = new StopWatch();
bool inRace = false;
async void StartLapClick(object sender, System.EventArgs e)
{
if (!inRace)
{
inRace = true;
sw.Start();
updateTimer();
}
}
async void updateTimer()
{
await Task.Run(() =>
{
while(inRace)
{
string slc = sw.Elapsed.ToString();
Device.BeginInvokeOnMainThread(() =>
{
timerLbl.Text = slc;
});
Task.Delay(100).Wait();
}
});
}
No, your code has some issues (according to the Best Practices in Asynchronous Programming):
async void is bad - this will call your method in fire-and-forget fashion, you even can't get the errors from there. You should use it only for event handlers like StartLapClick, not for real methods like updateTimer
Task.Delay(100).Wait(); - Do not block on tasks, use await for this
replace the whole while loop with a simple timer, and remove the Task.Delay call
updateTimer(); - you're calling async method in synchronous fashion, which is also bad.
You have to update the UI from the UI thread. You could have a timer or something running in the background kicking out events periodically to be picked up and forwarded to the UI thread. Even if you did that, I don't know that the parallel task library is what you'd want to use. That's more focused on running many tasks... in parallel.
Try this:
Device.StartTimer(TimeSpan.FromSeconds(1.0), () => {
// Your code
};
I've started developing a Leap Motion app and this is driving me nuts. Whenever I exit the application, the code responsible for cleaning up the Leap Motion controller hangs on me.
public void CleanUp()
{
_lmController.RemoveListener(_lmListener);
_lmController.Dispose();
}
I create both the controller and the listener in my Main Thread in a presenter class:
public MainViewPresenter(IMainView view, IApplicationController applicationController)
{
_view = view;
_applicationController = applicationController;
_view.Presenter = this;
_lmListener.Frame += _lmListener_Frame;
_lmController.AddListener(_lmListener);
}
The Cleanup() method is also a presenter method called on the view's FormClosing event. The weird thing is that it works perfectly fine when I call it from _listener_Frame(), which runs on a separate, Leap Motion-created no-name thread!
_lmListener_Frame() itself resides in the presenter. It just gets data from _lmController, creates a view model and sends it to the view, which in turn uses Invoke to update the display data.
I've tried calling the CleanUp stuff in Dispose() (both the view and the presenter (not redundant of course)) and that also doesn't work.
I admit that I'm not an expert in threading, but I can't see how there's any conflict going on here, and why RemoveListener works from controller thread, but not from the Main Thread, where the listener was actually added. Any help is appreciated!
SOLUTION
Completely by chance, I've found the solution today! It turns out that the "Invoke" call was the culprit, and it should've been BeginInvoke all this time, although this isn't mentioned anywhere in the WinForms setup guide. I'm guessing it was causing a deadlock with the controller thread and after the first GUI update it was bound to crash.
In a Windows forms Application, the following worked for me:
protected override void Dispose(bool disposing)
{
try
{
if (disposing)
{
if (components != null)
{
components.Dispose();
}
this.controller.RemoveListener(this.listener);
this.controller.Dispose();
}
}
finally
{
base.Dispose(disposing);
}
}
}
I wrote it awhile ago, though, and don't remember why it needed to be more complicated than what you tried. (Full example here: https://developer.leapmotion.com/documentation/csharp/devguide/Project_Setup_WinForms.html)
I'm trying to do a simple chat application on javafx
my actual problem is the thread to insert updates into a observablelist and set it on a listview
the code im using :
String message_reçu;
try {
out = new PrintWriter(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (true) {
message_reçu = in.readLine();
if (message_reçu != null) {
messagesReçus.add(message_reçu);
}
if (message_reçu.equals("QUIT")) {
break;
}
}
in.close();
out.close();
socket.close();
I did this inside of a runnable class and once the server fire a msg the thread insert the msg on the list and shows on the listview but the thread dies instead of keep the work
I did a search on it and every one says to use a runlater but I’m completely lost there I did declare a runlater but I’m not sure how to execute it so any help is welcome
Thanks
Other Answers
This question is largely a duplicate of the following questions, so also refer to the answers to those:
Usage of JavaFX Platform.runLater and access to UI from a different thread
Platform.runLater and Task in JavaFX
Solution
Your question is little more specific than those though, so I'll provide some extra info.
For your particular code you want to wrap the add call in Platform.runLater:
Platform.runLater(new Runnable() {
public void run() {
messagesReçus.add(message_reçu);
}
});
Everything else in your example stays as it is.
Background Information
JavaFX UI updates must be made on the JavaFX application thread or there is a high likelihood that your program will malfunction in unexpected ways.
The ListView control listens for changes to the ObservableList backing the ListView cell values. When that list changes, a UI update is immediately triggered on the thread the originally updated the list.
Once you wrap the list modifications in Platform.runLater, you ensure that the subsequently triggered UI update is performed on the JavaFX application thread rather than your user thread.
today I've added multi threading to a windows forms application. On my UI thread I'm starting a thread via new Thread() {...}).Start(); Which itself will call a Method which uses ThreadPool.QueueUserWorkItem(). After the Method is called the thread will wait on a queue until a specific item is returned and the thread exits:
new Thread(o =>
{
s.SimulateChanges();
Boolean run = true;
while (run)
{
SimulationResult sr = queue.WaitDequeue();
//EOF is a static property which will be returned
//if the queue is at its end so I can break the while loop
if (SimulationResult.EOF.Equals(sr))
{
run = false;
continue;
}
this.simulationProgressBar.BeginInvoke((Action)delegate()
{
if (sr.IsDummy && this.simulationProgressBar.Value < this.simulationProgressBar.Maximum)
{
/*...*/
}
else
{
this.resultListView.AddObject(sr);
}
});
}
this.simulationProgressBar.BeginInvoke((Action)delegate()
{
this.ToggleSimulationControls(true);
});
}).Start();
And that is the code of the method called:
public void SimulateChanges()
{
ThreadPool.QueueUserWorkItem(o =>
{
foreach (IColElem elem in collection.AsEnumerable())
{
/*lot of code*/
queue.Enqueue(new SimulationResult() { IsDummy = true });
}
log.Debug("Finished!");
queue.Enqueue(SimulationResult.EOF);
});
}
My Queue is a self written class allowing a thread to wait on dequeue until an object ins enqueued.
Everything is working fine, except that if I stop debugging (using stop debugging or simply closing the application) I can't rebuild my application as VS2010 doesn't remove the file handle. I believe it has something to do with my threads not exiting correctly. Is their any way I can assure this?
Thanks for any advice :-)
Hard to explain all aspects of the question. But you are making a pretty common mistake, often made by programmers when they first start using threads. You are not making sure that the thread stops running when the user closes the main window. It is an easy mistake to make, the UI thread takes care of a lot of grunt work. Including automatically terminating when the main window of your app is closed by the user. So at least part of your problem is that you did manage to close the main window. But didn't actually terminate the process. Building cannot work, your program's EXE is still in use.
Properly shutting down a thread can be very difficult, given that the user will close the window regardless of what that thread is doing. It could be catatonic, buried deep inside an operating system call and waiting for it to complete. Tough to ask it to quit when it isn't executing code.
There is a very simple solution, at least good enough to keep going with your project or solve half the problem you have. You can mark the thread as "kill automatically at program termination" and the CLR will take care of it. Use the IsBackground property, like this:
var t = new Thread(o =>
{
// Lotsa code
});
t.IsBackground = true;
t.Start();
But do keep in mind that there's nothing graceful about that kind of kill. If you are writing a file or talking to a server then that's going to cause a partially written file or a very confused server. Otherwise not different from killing the program with task manager.