After adding multi threading to my app, VS2010 will not remove file handle after stopping debugging - multithreading

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.

Related

Parellel Task Library vs UI Thread Xamarin.Forms when constantly updating the UI

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
};

Getting error "attempting to detach while still running code" when calling JavaVm->DetachCurrentThread [duplicate]

I have an Android app that uses NDK - a regular Android Java app with regular UI and C++ core. There are places in the core where I need to call Java methods, which means I need a JNIEnv* for that thread, which in turn means that I need to call JavaVM->AttachCurrentThread() to get the valid env.
Previously, was just doing AttachCurrentThread and didn't bother to detach at all. It worked fine in Dalvik, but ART aborts the application as soon as a thread that has called AttachCurrentThread exits without calling DetachCurrentThread. So I've read the JNI reference, and indeed it says that I must call DetachCurrentThread. But when I do that, ART aborts the app with the following message:
attempting to detach while still running code
What's the problem here, and how to call DetachCurrentThread properly?
Dalvik will also abort if the thread exits without detaching. This is implemented through a pthread key -- see threadExitCheck() in Thread.cpp.
A thread may not detach unless its call stack is empty. The reasoning behind this is to ensure that any resources like monitor locks (i.e. synchronized statements) are properly released as the stack unwinds.
The second and subsequent attach calls are, as defined by the spec, low-cost no-ops. There's no reference counting, so detach always detaches, no matter how many attaches have happened. One solution is to add your own reference-counted wrapper.
Another approach is to attach and detach every time. This is used by the app framework on certain callbacks. This wasn't so much a deliberate choice as a side-effect of wrapping Java sources around code developed primarily in C++, and trying to shoe-horn the functionality in. If you look at SurfaceTexture.cpp, particularly JNISurfaceTextureContext::onFrameAvailable(), you can see that when SurfaceTexture needs to invoke a Java-language callback function, it will attach the thread, invoke the callback, and then if the thread was just attached it will immediately detach it. The "needsDetach" flag is set by calling GetEnv to see if the thread was previously attached.
This isn't a great thing performance-wise, as each attach needs to allocate a Thread object and do some internal VM housekeeping, but it does yield the correct behavior.
I'll try a direct and practical approach (with sample code, without use of classes) answering this question for the occasional developer that came up with this error in android, in cases where they had it working and after a OS or framework update (Qt?) it started to give problems with that error and message.
JNIEXPORT void Java_com_package_class_function(JNIEnv* env.... {
JavaVM* jvm;
env->GetJavaVM(&jvm);
JNIEnv* myNewEnv; // as the code to run might be in a different thread (connections to signals for example) we will have a 'new one'
JavaVMAttachArgs jvmArgs;
jvmArgs.version = JNI_VERSION_1_6;
int attachedHere = 0; // know if detaching at the end is necessary
jint res = jvm->GetEnv((void**)&myNewEnv, JNI_VERSION_1_6); // checks if current env needs attaching or it is already attached
if (JNI_EDETACHED == res) {
// Supported but not attached yet, needs to call AttachCurrentThread
res = jvm->AttachCurrentThread(reinterpret_cast<JNIEnv **>(&myNewEnv), &jvmArgs);
if (JNI_OK == res) {
attachedHere = 1;
} else {
// Failed to attach, cancel
return;
}
} else if (JNI_OK == res) {
// Current thread already attached, do not attach 'again' (just to save the attachedHere flag)
// We make sure to keep attachedHere = 0
} else {
// JNI_EVERSION, specified version is not supported cancel this..
return;
}
// Execute code using myNewEnv
// ...
if (attachedHere) { // Key check
jvm->DetachCurrentThread(); // Done only when attachment was done here
}
}
Everything made sense after seeing the The Invocation API docs for GetEnv:
RETURNS:
If the current thread is not attached to the VM, sets *env to NULL, and returns JNI_EDETACHED. If the specified version is not supported, sets *env to NULL, and returns JNI_EVERSION. Otherwise, sets *env to the appropriate interface, and returns JNI_OK.
Credits to:
- This question Getting error "attempting to detach while still running code" when calling JavaVm->DetachCurrentThread that in its example made it clear that it was necessary to double check every time (even though before calling detach it doesn't do it).
- #Michael that in this question comments he notes it clearly about not calling detach.
- What #fadden said: "There's no reference counting, so detach always detaches, no matter how many attaches have happened."

Swift: Async callback in command line utility [duplicate]

I am writing a command line application in Swift using a third-party framework that (if I understand the code correctly) relies on GCD callbacks to complete certain actions when a socket receives data. In order to better understand the framework, I have been playing around with a sample Cocoa application the framework's author wrote to go along with the framework.
Because the sample application is a Cocoa application, the run loops are handled automatically. I'm including snippets of code from the sample application (MIT license) to give an idea of how it works:
class AppDelegate: NSObject, NSApplicationDelegate {
var httpd : Connect!
func startServer() {
httpd = Connect()
.onLog {
[weak self] in // unowned makes this crash
self!.log($0)
}
.useQueue(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0))
...
httpd.listen(1337)
}
...
func applicationDidFinishLaunching(aNotification: NSNotification?) {
startServer()
...
}
}
I'd like to modify the sample application to run from the command line. When I put the startServer() function into a command line application, it runs, but the socket is immediately closed after it is opened, and the program finishes executing with an exit code 0. This is expected behavior, as there are no run loops in an Xcode command line project, and thus the program doesn't know to wait for the socket to receive data.
I believe the correct way to get the socket to stay open and the program to continuously run would be to put the main thread in a CFRunLoop. I have looked over Apple's documentation and, except for the basic API reference, there is nothing on threading in Swift. I have looked at third party resources, but they all involve alternate threads in iOS and Cocoa applications. How do I properly implement a CFRunLoop for the main thread?
It seems like Martin R's answer should work, however I was able to get the socket to stay open with a single function call. At the end of the startServer() function, I put the line:
CFRunLoopRun()
Which worked.
The NSRunLoop Class Reference
has an example for a simple runloop:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
which can be translated to Swift:
var shouldKeepRunning = true // global
let theRL = NSRunLoop.currentRunLoop()
while shouldKeepRunning && theRL.runMode(NSDefaultRunLoopMode, beforeDate: NSDate.distantFuture()) { }
Alternatively, it might be sufficient to just call
dispatch_main()
Update for Swift 3.1:
let theRL = RunLoop.current
while shouldKeepRunning && theRL.run(mode: .defaultRunLoopMode, before: .distantFuture) { }
or
dispatchMain()

How to make an assert window in QT

I currently have a very long running GUI-Application in QT. Later that application is going to be tested and run on an embedded device without a keyboard in full screen.
For easier debugging I have a custom assert macro, which allows me to ignore certain asserts (may include known buggy parts I have to work around for now) etc. For the time being I just print something on the console such as "Assertion: XXXX failed; abort/ignore". This is fine when I start the application within a console, but ultimately fails when I run it on the final device. In that case the assert will just block the main thread waiting for input and make the GUI hang badly without hope for recovery.
Now I am thinking about how to remedy this situation. One Idea is to just have the assert crash, as the standard assert does. But I do not really like that Idea, since there are a lot of know problems, and I've always found ignorable asserts very helpful when testing applications. Also I would have to put the messages into a separate file, so I can later see what happened while testing. Reading these files afterwards is possible, but I would prefer a simpler way to find out what went wrong.
The other idea was to make a window instead. However the asserts may be triggered in any thread and I can only create new windows in the GUI thread. Also the main event loop may be blocked by the assert, so I cannot be sure that it will handle the events correctly. I would somehow need a fully responsive stand-alone window in a separate thread, which only handles a few buttons.
Is this somehow possible in QT4?
You may post events to main thread to display dialog and wait for an answer from non-gui threads, or just display dialog if current thread is app thread
int result = -1;
if ( QTrhead::currentThread() == QCoreApplication::instance()->thread() )
{
result = AssertHandler->ShowDialog(where, what, condition);
}
else
{
QMetaObject::invokeMethod(AssertHandler, "ShowDialog", Qt::QueuedBlockingConnection, Q_RETURN_ARG(int, result), Q_ARG(QString, where), Q_ARG(QString, what), Q_ARG(QString, condition);
}
if (result != 0)
{
// handle assert
}
The AssertHandler is QObject based class with slot int ShowDialog(const QString &where, const QString what, const QString &condition). It should display dialog with assert data and buttons assert/ignore. Returns 0 when user pressed ignore, otherwise returns non zero value.

QNetworkAccessManager crashes on delete

I have a class 'Downloader' derived from QObject that runs in a worker thread. When the thread is started, the downloader creates a QNetworkAccessManager object on the heap, and starts to request files. I keep track of how many files have been requested and received. Once I've gotten all of the files, I delete the QNetworkAccessManager object and exit the thread. My problem is that deleting the manager object causes a crash no matter when or where I do this. I've even tried manager->deleteLater(). If I don't delete it, my code runs great, but I know there is a memory leak there. Here is a stripped down version of my code.
Creating the downloader and thread, and setting signals up so that starting the thread starts the downloads, and when the downloads are complete, the thread stops:
QThread thread;
Downloader downloader;
downloader.setFiles(files);
downloader.moveToThread(&thread);
downloader.connect(&thread, SIGNAL(started()), SLOT(downloadFiles()));
thread.connect(&downloader, SIGNAL(downloadsFinished()), SLOT(quit()));
thread.start();
Implementation for the downloader:
void Downloader::downloadFiles()
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(finished(QNetworkReply*)));
receivedCount = 0;
requestCount = files.count();
for (QStringList::const_iterator pos = files.begin(); pos != files.end(); ++pos)
{
QUrl url(*pos);
manager->get(QNetworkRequest(url));
}
}
void Downloader::finished(QNetworkReply *reply)
{
// *** Get the file data and process it *** //
++receivedCount;
reply->deleteLater();
if (receivedCount == requestCount)
{
// manager->deleteLater();
emit downloadsFinished();
}
}
The commented out line will crash the app. Even deleting the manager in Downloader's destructor, or setting the downloader as the manager's parent will crash the app.
I first tried creating the manager as a regular member variable on the stack, but doing so causes errors of it's own since the manager would be created in the GUI thread and later try to create children on a different thread.
And before anybody says "QNetworkAccessManager is asynchronous. Why use it in a worker thread?" I have my reasons. It shouldn't be THAT unheard of to do something like this.
The only obvious problem is below but I am not sure if you have posted your entire code or not
void Downloader::downloadFiles()
{
QNetworkAccessManager *manager = new QNetworkAccessManager();
You are creating a local QNetworkAccessManager *manager in your method but not keeping a reference to it and then trying to access it within finished() method.
You should assign new QNetworkAccessManager(); a member variable !

Resources