I am running the following code when i click on a button:
foreach (string item in urlQueue)
{
log("creating job " + iia.ToString());
_smartThreadPool.QueueWorkItem(
new Amib.Threading.Func<string, int, int, string, int>(checkURLSmart),
item, iia, 5000, kryptonTextBox1.Text);
iia++;
}
Application.DoEvents();
_smartThreadPool.Start();
_smartThreadPool.WaitForIdle();
_smartThreadPool.Shutdown();
For some reason this is blocking the UI thread, any ideas how to fix this? I want the UI to be responsive while the queue is working
You shouldn't call WaitForIdle() in GUI thread.
Use http://msdn.microsoft.com/en-us/library/a06c0dc2.aspx in .NET or http://docs.oracle.com/javase/7/docs/api/javax/swing/SwingUtilities.html invokeLater() in Java instead.
This mechanism put your code in queue for execution in GUI thread. So you are able to update GUI view with processed data in callback parameters.
Also see explanation about differences between Invoke & BeginInvoke: What's the difference between Invoke() and BeginInvoke()
Related
In the default example app whenever you create new fultter project I just added the following code.
initState() {
super.initState();
loop();
}
loop() async {
while (true) {
await Future.delayed(Duration(milliseconds: 10));
print("count now:$_counter");
}
}
Why is the app UI is not getting blocked? I am able to click + button and the counter increases smoothly. Even if I change the delay to 10 sec, the UI is resposive.
Is the loop() runnning in different thread?but I know dart is single thread. How is it possible?
Where the loop function is running?
Can I use this technique to run background task for example checking id my sqflite table rows are synced with cloud etc???
Await calls are non-blocking.
The way this works is, while Dart is single-threaded, some Dart code delegate their implementation to the Dart VM.
Things like file reads or HTTP requests are performed outside of Dart (either by the browser or in c++), in a different thread.
So while Dart is single-threaded, it is still able to perform multiple tasks simultaneously without locking the UI.
I am trying to use titanium execution contexts to produce parallel code execution between the main application context and others. I am using CreateWindow with a url property refers to a .js file inside "lib" folder. But by logging the execution on both iOS and Android devices it seems that different contexts are executed on the app main thread, no parallelism here.
My new context trigger inside my Alloy controller:
var win2 = Ti.UI.createWindow({
title: 'New Window',
url: 'thread.js',
backgroundColor:'#fff'
});
win2.open();
Ti.API.log('after open');
My thread.js contents:
Ti.API.log("this is the new context");
Ti.App.fireEvent("go" , {});
while(true)
{
Ti.API.log('second context');
}
This while loop apparently blocks the main context (my Alloy controller) waiting it to exit.
Any suggestions of how can I execute some code (mainly heavy sqlite db access) in background so that the UI be responsive? (Web workers are not a choice for me).
You could try to achieve the wanted behaviour with a setInterval() or setTimeout() method.
setInterval()[source]:
function myFunc() {
//your code
}
//set the interval
setInterval(myFunc,2000) //this will run the function for every 2 sec.
Another suggested method would be to fire a custom event when you need the background behavior since it is processed in its own thread. This is also suggested in the official documentation.
AFAIK, titanium is single threaded, because JavaScript is single threaded. You can get parallel execution with native modules, but you'll have to code that yourself for each platform.
Another option is to use web workers, but I consider that to be a hack.
I need help how to unfreeze my dialog box. I'm using MFC and I have an infinite loop I want to execute when a button is pressed. However, the dialog box freezes when the infinite loop starts. Now I looked at this thread where someone was having a similar problem.
Unfortunately I tried multithreading but I found out that It can't work for me because I'm using an api that uses OLE automation and I'm getting an unhandled memory exception. I think this is because program uses the serial port and i read somewhere you can only use the handle to the serial port in one thread.
My program is simply to see if someone has dialed in to my modem and wait for them to send me a file, then hangup. Here is my loop.
while(1)
{
//get rid of input buffer
ts->_this->m_pHAScript->haReleaseRemoteInput();
ts-> _this->textBox->SetWindowTextA("thread Commence");
//wait for connected
if(success = ts->_this->m_pHAScript->haWaitForString("CONNECT",timeout))
{
//getFile
if(success = ts->_this->m_pHAScript->haWaitForXfer(5000))
{
//hangup
ts->_this->haTypeText("+++ath\r");
}
}
}
Is there a way to unfreeze the dialog box?
Add this code inside while loop:
MSG msg;
while(PeekMessage(&msg, GetSafeHwnd(), 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
}
The GUI in Windows relies on a message loop - somewhere in your code, either explicitly or hidden in a framework, there's a loop that checks for a message in a queue and processes it. If anything blocks the code from returning to that loop, the GUI gets frozen.
There are a few ways around this. One was given by David Brabant, essentially duplicating the loop. Another is to start a new "worker" thread that runs the blocking operation independently. If your message loop has a function that it calls when it is idle, i.e. no more messages are in the queue, you can do some processing there; that's not possible in your example however.
I have a problem with Silverlight application.
Suppose I have an xml file in resources stream. I get it as usual with something like this:
StreamResourceInfo sr =
Application.GetResourceStream(new Uri("uri goes there", UriKind.Relative));
var xml = XElement.Load(sr.Stream, LoadOptions.SetBaseUri);
And everything works just fine. But if the same code runs in the background thread (via async/await or, to be simple, in background worker) it always returns null.
I’ve heard about a bug in VS with similar problems (returning null) so I’ve tried to clean solution, delete obj folders etc. but nothing works — in background thread this code always return null for resources stream.
You can't access UI resources in background thread. Ideally you should access it in UI thread and pass it to background thread.
Background: I am using OmniThreadLibrary to load batch mode ADO stored procedures in the background. I am doing some slightly dodgy stuff by swapping the connection after opening the SP but that seems to be quite reliable. I'm using PostMessage to send messages back to the calling form and that works in my test applications. Primoz' comms channels work for me, I'm using those for inter-thread comms but for our main application I'm trying to avoid that dependency by using standard PostMessage calls as we do elsewhere in the app.
Problem: Unfortunately when I put this into our main application the PostMessage calls in the thread start failing with 1400:invalid window handle.
I have liberally added extra PostMessage calls and logging code to try to locate the problem, but I'm out of ideas now. The code is boilerplate:
const WM_PW_ADLQUEUEEMPTY = WM_USER + 11;
...
if PostMessage (OwnerHandle, WM_PW_ADLPROGRESS, QueueID, 10) then
pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') OK for Queue ' + IntToStr (QueueID))
else
pwDebugLog ('TADLQueue.Run WM_PW_ADLPROGRESS send to ' + IntToHex (OwnerHandle, 8) + ' (IsWindow '+BoolToStr(IsWindow(OwnerHandle),true)+') failed for Queue ' + IntToStr (QueueID));
But the log for a series of calls is not very revealing to me. note that the four hex digits after the time is the thread id from GetCurrentThreadID.
15:41:53.221 1614 TpwAsyncDataLoader.RunQueue WM_PW_ADLPROGRESS send to 00A5110C (IsWindow True) OK for Queue -6
15:41:53.265 13B4 TADLQueue.Run WM_PW_ADLPROGRESS send to 00A5110C (IsWindow True) OK for Queue -6
15:41:53.554 13B4 TADLQueueManager.WriteSysErrorMessageToDatabase Postmessage 00A5110C (IsWindow False) failed with 1400 Invalid window handle
Can anyone shed some light on this? I'm confused at how a window handle can become invalid while I'm looking at it, but that's what it looks like to me.
The one thing I can think of is that the form I'm showing here isn't processing messages and I'm seeing a "message queue full" failure rather than the IsWindow(handle) failure that it looks like. How can I test for that?
There are cases where a handle gets recreated, most notably when you change window flags. This might be what's happening in your application.
All I found so far about recreating windows handle is this post from Allen Bauer but I'm certain reading a more detailed one written by Peter Below. Unfortunatly I can't seem to find that one.
Finally, you need to be aware of cases
where your handle may need to get
recreated. This can happen if the
surrounding form or the parent
component's handle goes through a
recreate process. Up until more recent
releases of Windows, the only way to
change some window flags was to
destroy the handle and recreate with
new flags in the CreateWindowEx()
call. There are many components that
still do this. You know if you're in a
recreate situation by checking
(csRecreating in ControlState).
Edit
Not actually the posts from Peter I had in mind but it might give you some fresh ideas.
The form will not have a handle until
you show it the first time (unless
something in the form load sequence
request the handle) but the handle is
not destroyed when you hide the form
and unless you do something that
forces the form to recreate the
handle, e.g. change its border style
or border icons, or call RecreateWnd
yourself the handle will stay the
same.
It may not be desirable but it cannot
be avoided, at least not the way
Delphi drag&dock is currently
implemented. When you dock the dragged
form to another form it becomes a
control (with WS_CHILD window style)
and that means that its window handle
has to be destroyed and recreated with
the new style. And destroying the
window handle of a container control
automatically destroys the handles for
all child controls as well.
and
There is also the fact that the forms
window handle is destroyed and
recreated when you assign to its
Parent property. This also destroys
and recreates the handles for all
controls on the form.
I had a similar issue (but in VC++2010), and I did not find the solution on any forum, so I post it here, hope this will help:
Issue:
Creating a thread,
Passing the HWnd handle
In the thread, PostMessage
throws a 1400 error (invalid handle), although the pointer was equal
with the handle as seen from UI thread (with GetSafeHWnd()).
Solution:
Do not pass the handle, but the parent CDialog(Ex) class
This class has a m_hWnd member that will do the job
Here is a (Cpp) example, sorry for the cast mess.
// In the worker thread
ThreadParam *threadParam = (ThreadParam*)param
// This is ugly because my pointer is a void *, to avoid one more forward declaration
CCoreGenDlg *dlg = static_cast<CCoreGenDlg *>(threadParam->ptr);
// Post
bool b = PostMessage(dlg->m_hWnd ,1221,0,(LPARAM)message);
Cheers'