NUnit OneTimeTearDown Garbage collection best practice - garbage-collection

At first, I have declared the variables at the beginning of my class
private AddressRepository sut;
private Mock<TransactionDbContext> mockDBContext;
In the OneTimeSetUp, I have created the set up code
[OneTimeSetUp]
public void Setup()
{
var options = new DbContextOptionsBuilder<TransactionDbContext>().Options;
mockDBContext = new Mock<TransactionDbContext>(options);
var dbSetMock = new Mock<DbSet<Address>>();
var data = ValueTask.FromResult(new Address() { AddressLine1 = "address line 1"
});
dbSetMock.Setup(s => s.FindAsync(It.IsAny<Guid>())).Returns(data);
mockDBContext.Setup(s => s.Set<Address>()).Returns(dbSetMock.Object);
}
Question, do I need to write additional code to handle garbage collection, or should I unassign all variables as following to speeds up GC?
[OneTimeTearDown]
public void TearDown()
{
//unassign all variables
mockDBContext = null;
sut = null;
//Possibly call GC.Collect?
GC.Collect();
}
Any coding advice will be well appreciated.

You should dispose of any disposable external resources, which you acquire. Where you do this depends on where you acquire the resource.
If you acquire it in your test fixture constructor, then let NUnit dispose of it. You do that by having the fixture class implement IDispose.
If you acquire it in a OneTimeSetUp, then dispose of it in the corresponding OneTimeTearDown.
If you acquire it in a SetUp, then dispose of it in the corresponding TearDown.
If you acuire it in a TestMethod, then dispose of it before that method returns. The simplest way to do this is via using.
All that said and explained, your example doesn't seem to acquire any disposable external resources. So I would not do any of those things. :-)
Generally, the time people spend figuring out overly complicated code outweighs any small advantage in efficiency. So wait till you see a performance problem before you fix it.

Related

New Thread doesn't open scene [duplicate]

I'm trying to understand how threads works in java. This is a simple database request that returns a ResultSet. I'm using JavaFx.
package application;
import java.sql.ResultSet;
import java.sql.SQLException;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
public class Controller{
#FXML
private Button getCourseBtn;
#FXML
private TextField courseId;
#FXML
private Label courseCodeLbl;
private ModelController mController;
private void requestCourseName(){
String courseName = "";
Course c = new Course();
c.setCCode(Integer.valueOf(courseId.getText()));
mController = new ModelController(c);
try {
ResultSet rs = mController.<Course>get();
if(rs.next()){
courseCodeLbl.setText(rs.getString(1));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// return courseName;
}
public void getCourseNameOnClick(){
try {
// courseCodeLbl.setText(requestCourseName());
Thread t = new Thread(new Runnable(){
public void run(){
requestCourseName();
}
}, "Thread A");
t.start();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
This returns an exception:
Exception in thread "Thread A" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread A
How do I correctly implement threading so that every database request is executed in a second thread instead of the main thread?
I've heard of implementing Runnable but then how do I invoke different methods in run method?
Never worked with threading before but I thought it's time for it.
Threading Rules for JavaFX
There are two basic rules for threads and JavaFX:
Any code that modifies or accesses the state of a node that is part of a scene graph must be executed on the JavaFX application thread. Certain other operations (e.g. creating new Stages) are also bound by this rule.
Any code that may take a long time to run should be executed on a background thread (i.e. not on the FX Application Thread).
The reason for the first rule is that, like most UI toolkits, the framework is written without any synchronization on the state of elements of the scene graph. Adding synchronization incurs a performance cost, and this turns out to be a prohibitive cost for UI toolkits. Thus only one thread can safely access this state. Since the UI thread (FX Application Thread for JavaFX) needs to access this state to render the scene, the FX Application Thread is the only thread on which you can access "live" scene graph state. In JavaFX 8 and later, most methods subject to this rule perform checks and throw runtime exceptions if the rule is violated. (This is in contrast to Swing, where you can write "illegal" code and it may appear to run fine, but is in fact prone to random and unpredictable failure at arbitrary time.) This is the cause of the IllegalStateException you are seeing: you are calling courseCodeLbl.setText(...) from a thread other than the FX Application Thread.
The reason for the second rule is that the FX Application Thread, as well as being responsible for processing user events, is also responsible for rendering the scene. Thus if you perform a long-running operation on that thread, the UI will not be rendered until that operation is complete, and will become unresponsive to user events. While this won't generate exceptions or cause corrupt object state (as violating rule 1 will), it (at best) creates a poor user experience.
Thus if you have a long-running operation (such as accessing a database) that needs to update the UI on completion, the basic plan is to perform the long-running operation in a background thread, returning the results of the operation when it is complete, and then schedule an update to the UI on the UI (FX Application) thread. All single-threaded UI toolkits have a mechanism to do this: in JavaFX you can do so by calling Platform.runLater(Runnable r) to execute r.run() on the FX Application Thread. (In Swing, you can call SwingUtilities.invokeLater(Runnable r) to execute r.run() on the AWT event dispatch thread.) JavaFX (see later in this answer) also provides some higher-level API for managing the communication back to the FX Application Thread.
General Good Practices for Multithreading
The best practice for working with multiple threads is to structure code that is to be executed on a "user-defined" thread as an object that is initialized with some fixed state, has a method to perform the operation, and on completion returns an object representing the result. Using immutable objects, in particular, a record, for the initialized state and computation result is highly desirable. The idea here is to eliminate the possibility of any mutable state being visible from multiple threads as far as possible. Accessing data from a database fits this idiom nicely: you can initialize your "worker" object with the parameters for the database access (search terms, etc). Perform the database query and get a result set, use the result set to populate a collection of domain objects, and return the collection at the end.
In some cases it will be necessary to share mutable state between multiple threads. When this absolutely has to be done, you need to carefully synchronize access to that state to avoid observing the state in an inconsistent state (there are other more subtle issues that need to be addressed, such as liveness of the state, etc). The strong recommendation when this is needed is to use a high-level library to manage these complexities for you.
Using the javafx.concurrent API
JavaFX provides a concurrency API that is designed for executing code in a background thread, with API specifically designed for updating the JavaFX UI on completion of (or during) the execution of that code. This API is designed to interact with the java.util.concurrent API, which provides general facilities for writing multithreaded code (but with no UI hooks). The key class in javafx.concurrent is Task, which represents a single, one-off, unit of work intended to be performed on a background thread. This class defines a single abstract method, call(), which takes no parameters, returns a result, and may throw checked exceptions. Task implements Runnable with its run() method simply invoking call(). Task also has a collection of methods which are guaranteed to update state on the FX Application Thread, such as updateProgress(...), updateMessage(...), etc. It defines some observable properties (e.g. state and value): listeners to these properties will be notified of changes on the FX Application Thread. Finally, there are some convenience methods to register handlers (setOnSucceeded(...), setOnFailed(...), etc); any handlers registered via these methods will also be invoked on the FX Application Thread.
So the general formula for retrieving data from a database is:
Create a Task to handle the call to the database.
Initialize the Task with any state that is needed to perform the database call.
Implement the task's call() method to perform the database call, returning the results of the call.
Register a handler with the task to send the results to the UI when it is complete.
Invoke the task on a background thread.
For database access, I strongly recommend encapsulating the actual database code in a separate class that knows nothing about the UI (Data Access Object design pattern). Then just have the task invoke the methods on the data access object.
So you might have a DAO class like this (note there is no UI code here):
public class WidgetDAO {
// In real life, you might want a connection pool here, though for
// desktop applications a single connection often suffices:
private Connection conn ;
public WidgetDAO() throws Exception {
conn = ... ; // initialize connection (or connection pool...)
}
public List<Widget> getWidgetsByType(String type) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement("select * from widget where type = ?")) {
pstmt.setString(1, type);
ResultSet rs = pstmt.executeQuery();
List<Widget> widgets = new ArrayList<>();
while (rs.next()) {
Widget widget = new Widget();
widget.setName(rs.getString("name"));
widget.setNumberOfBigRedButtons(rs.getString("btnCount"));
// ...
widgets.add(widget);
}
return widgets ;
}
}
// ...
public void shutdown() throws Exception {
conn.close();
}
}
Retrieving a bunch of widgets might take a long time, so any calls from a UI class (e.g a controller class) should schedule this on a background thread. A controller class might look like this:
public class MyController {
private WidgetDAO widgetAccessor ;
// java.util.concurrent.Executor typically provides a pool of threads...
private Executor exec ;
#FXML
private TextField widgetTypeSearchField ;
#FXML
private TableView<Widget> widgetTable ;
public void initialize() throws Exception {
widgetAccessor = new WidgetDAO();
// create executor that uses daemon threads:
exec = Executors.newCachedThreadPool(runnable -> {
Thread t = new Thread(runnable);
t.setDaemon(true);
return t ;
});
}
// handle search button:
#FXML
public void searchWidgets() {
final String searchString = widgetTypeSearchField.getText();
Task<List<Widget>> widgetSearchTask = new Task<List<Widget>>() {
#Override
public List<Widget> call() throws Exception {
return widgetAccessor.getWidgetsByType(searchString);
}
};
widgetSearchTask.setOnFailed(e -> {
widgetSearchTask.getException().printStackTrace();
// inform user of error...
});
widgetSearchTask.setOnSucceeded(e ->
// Task.getValue() gives the value returned from call()...
widgetTable.getItems().setAll(widgetSearchTask.getValue()));
// run the task using a thread from the thread pool:
exec.execute(widgetSearchTask);
}
// ...
}
Notice how the call to the (potentially) long-running DAO method is wrapped in a Task which is run on a background thread (via the accessor) to prevent blocking the UI (rule 2 above). The update to the UI (widgetTable.setItems(...)) is actually executed back on the FX Application Thread, using the Task's convenience callback method setOnSucceeded(...) (satisfying rule 1).
In your case, the database access you are performing returns a single result, so you might have a method like
public class MyDAO {
private Connection conn ;
// constructor etc...
public Course getCourseByCode(int code) throws SQLException {
try (PreparedStatement pstmt = conn.prepareStatement("select * from course where c_code = ?")) {
pstmt.setInt(1, code);
ResultSet results = pstmt.executeQuery();
if (results.next()) {
Course course = new Course();
course.setName(results.getString("c_name"));
// etc...
return course ;
} else {
// maybe throw an exception if you want to insist course with given code exists
// or consider using Optional<Course>...
return null ;
}
}
}
// ...
}
And then your controller code would look like
final int courseCode = Integer.valueOf(courseId.getText());
Task<Course> courseTask = new Task<Course>() {
#Override
public Course call() throws Exception {
return myDAO.getCourseByCode(courseCode);
}
};
courseTask.setOnSucceeded(e -> {
Course course = courseTask.getCourse();
if (course != null) {
courseCodeLbl.setText(course.getName());
}
});
exec.execute(courseTask);
The API docs for Task have many more examples, including updating the progress property of the task (useful for progress bars..., etc.
Related
JavaFX - Background Thread for SQL Query
Sample for accessing a local database from JavaFX using concurrent tasks for database operations so that the UI remains responsive.
Exception in thread "Thread A" java.lang.IllegalStateException: Not on FX application thread; currentThread = Thread A
The exception is trying to tell you that you are trying to access JavaFX scene graph outside the JavaFX application thread. But where ??
courseCodeLbl.setText(rs.getString(1)); // <--- The culprit
If I can't do this how do I use a background thread?
The are different approaches which leads to similar solutions.
Wrap you Scene graph element with Platform.runLater
There easier and most simple way is to wrap the above line in Plaform.runLater, such that it gets executed on JavaFX Application thread.
Platform.runLater(() -> courseCodeLbl.setText(rs.getString(1)));
Use Task
The better approach to go with these scenarios is to use Task, which has specialized methods to send back updates. In the following example, I am using updateMessage to update the message. This property is bind to courseCodeLbl textProperty.
Task<Void> task = new Task<Void>() {
#Override
public Void call() {
String courseName = "";
Course c = new Course();
c.setCCode(Integer.valueOf(courseId.getText()));
mController = new ModelController(c);
try {
ResultSet rs = mController.<Course>get();
if(rs.next()) {
// update message property
updateMessage(rs.getString(1));
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
public void getCourseNameOnClick(){
try {
Thread t = new Thread(task);
// To update the label
courseCodeLbl.textProperty.bind(task.messageProperty());
t.setDaemon(true); // Imp! missing in your code
t.start();
} catch (NumberFormatException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This has nothing to do with database. JavaFx, like pretty much all GUI libraries, requires that you only use the main UI thread to modify the GUI.
You need to pass the data from the database back to the main UI thread. Use Platform.runLater() to schedule a Runnable to be run in the main UI thread.
public void getCourseNameOnClick(){
new Thread(new Runnable(){
public void run(){
String courseName = requestCourseName();
Platform.runLater(new Runnable(){
courseCodeLbl.setText(courseName)
});
}
}, "Thread A").start();
}
Alternatively, you can use Task.

Using mutex with NInject provider to prevent multi-threading concurrency access

In my Asp.Net MVC projects, I use NInject providers to create instances of UnitOfWork. (I use Mindscape.LightSpeed)
Here is a sample of binding in my NinjectModule class:
base.Bind<IUnitOfWork>().ToProvider(UnitOfWorkProvider<UnitOfWork>.CreateInstance(_lightSpeedContext, UnitOfWorkProvider.CreateUnitOfWork)).InRequestScope();
And here is an example of what I'm doing in the provider to create instances:
protected override T CreateInstance(IContext context)
{
T unitOfWork = default(T);
unitOfWork = this.CreateUnitOfWork();
if (this.ConnectionStrategy != null)
unitOfWork.ConnectionStrategy = this.ConnectionStrategy;
return unitOfWork;
}
Should it be better to use mutex object like the example below?
private static readonly Mutex _mutex = new Mutex();
protected override T CreateInstance(IContext context)
{
_mutex.WaitOne();
try
{
T unitOfWork = default(T);
unitOfWork = this.CreateUnitOfWork();
if (this.ConnectionStrategy != null)
unitOfWork.ConnectionStrategy = this.ConnectionStrategy;
return unitOfWork;
}
finally
{
_mutex.ReleaseMutex();
}
}
I don't found any example of using mutex with Ninject provider on the Net and this is why I ask the question.
It would be nice to have an explanation of why mutex is or not good in the context of Asp.Net MVC.
Thank you very much.
Why do you want to use mutex, when you are declaring your IUnitOfWork in request scope?
It would be bottle-neck for your web application, because parallel requests will be waiting for another to create an instance of IUnitOfWork. Widely used practice is to create one instance of unit of work or database context (connection) etc. per web request (IDisposable objects will be disposed at the end of the request). Even if you declare your component InSingletonScope, Ninject should take care of concurrency issues.

Streamwriter, StringBuilder and Parallel loops

Sorry for big chunk of code, I couldn't explain that with less.Basically I'm trying to write into a file from many tasks.
Can you guys please tell me what I'm doing wrong? _streamWriter.WriteLine() throws the ArgumentOutOfRangeException.
class Program
{
private static LogBuilder _log = new LogBuilder();
static void Main(string[] args)
{
var acts = new List<Func<string>>();
var rnd = new Random();
for (int i = 0; i < 10000; i++)
{
acts.Add(() =>
{
var delay = rnd.Next(300);
Thread.Sleep(delay);
return "act that that lasted "+delay;
});
}
Parallel.ForEach(acts, act =>
{
_log.Log.AppendLine(act.Invoke());
_log.Write();
});
}
}
public class LogBuilder : IDisposable
{
public StringBuilder Log = new StringBuilder();
private FileStream _fileStream;
private StreamWriter _streamWriter;
public LogBuilder()
{
_fileStream = new FileStream("log.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
_streamWriter = new StreamWriter(_fileStream) { AutoFlush = true };
}
public void Write()
{
lock (Log)
{
if (Log.Length <= 0) return;
_streamWriter.WriteLine(Log.ToString()); //throws here. Although Log.Length is greater than zero
Log.Clear();
}
}
public void Dispose()
{
_streamWriter.Close(); _streamWriter.Dispose(); _fileStream.Close(); fileStream.Dispose();
}
}
This is not a bug in StringBuilder, it's a bug in your code. And the modification you shown in your followup answer (where you replace Log.String with a loop that extracts characters one at a time) doesn't fix it. It won't throw an exception any more, but it won't work properly either.
The problem is that you're using the StringBuilder in two places in your multithreaded code, and one of them does not attempt to lock it, meaning that reading can occur on one thread simultaneously with writing occurring on another. In particular, the problem is this line:
_log.Log.AppendLine(act.Invoke());
You're doing that inside your Parallel.ForEach. You are not making any attempt at synchronization here, even though this will run on multiple threads at once. So you've got two problems:
Multiple calls to AppendLine may be in progress simultaneously on multiple threads
One thread may attempt to be calling Log.ToString at the same time as one or more other threads are calling AppendLine
You'll only get one read at a time because you are using the lock keyword to synchronize those. The problem is that you're not also acquiring the same lock when calling AppendLine.
Your 'fix' isn't really a fix. You've succeeded only in making the problem harder to see. It will now merely go wrong in different and more subtle ways. For example, I'm assuming that your Write method still goes on to call Log.Clear after your for loop completes its final iteration. Well in between completing that final iteration, and making the call to Log.Clear, it's possible that some other thread will have got in another call to AppendLine because there's no synchronization on those calls to AppendLine.
The upshot is that you will sometimes miss stuff. Code will write things into the string builder that then get cleared out without ever being written to the stream writer.
Also, there's a pretty good chance of concurrent AppendLine calls causing problems. If you're lucky they will crash from time to time. (That's good because it makes it clear you have a problem to fix.) If you're unlucky, you'll just get data corruption from time to time - two threads may end up writing into the same place in the StringBuilder resulting either in a mess, or completely lost data.
Again, this is not a bug in StringBuilder. It is not designed to support being used simultaneously from multiple threads. It's your job to make sure that only one thread at a time does anything to any particular instance of StringBuilder. As the documentation for that class says, "Any instance members are not guaranteed to be thread safe."
Obviously you don't want to hold the lock while you call act.Invoke() because that's presumably the very work you want to parallelize. So I'd guess something like this might work better:
string result = act();
lock(_log.Log)
{
_log.Log.AppendLine(result);
}
However, if I left it there, I wouldn't really be helping you, because this looks very wrong to me.
If you ever find yourself locking a field in someone else's object, it's a sign of a design problem in your code. It would probably make more sense to modify the design, so that the LogBuilder.Write method accepts a string. To be honest, I'm not even sure why you're using a StringBuilder here at all, as you seem to use it just as a holding area for a string that you immediately write to a stream writer. What were you hoping the StringBuilder would add here? The following would be simpler and doesn't seem to lose anything (other than the original concurrency bugs):
public class LogBuilder : IDisposable
{
private readonly object _lock = new object();
private FileStream _fileStream;
private StreamWriter _streamWriter;
public LogBuilder()
{
_fileStream = new FileStream("log.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
_streamWriter = new StreamWriter(_fileStream) { AutoFlush = true };
}
public void Write(string logLine)
{
lock (_lock)
{
_streamWriter.WriteLine(logLine);
}
}
public void Dispose()
{
_streamWriter.Dispose(); fileStream.Dispose();
}
}
I think the cause is because you are accessing the stringBuilder in the Parellel bracket
_log.Log.AppendLine(act.Invoke());
_log.Write();
and inside the LogBuilder you perform lock() to disallow memory allocation on stringBuidler. You are changing the streamwriter to handle the log in every character so would give the parellel process to unlock the memory allocation to stringBuilder.
Segregate the parallel process into distinct action would likely reduce the problem
Parallel.ForEach(acts, act =>
{
_log.Write(act.Invoke());
});
in the LogBuilder class
private readonly object _lock = new object();
public void Write(string logLines)
{
lock (_lock)
{
//_wr.WriteLine(logLines);
Console.WriteLine(logLines);
}
}
An alternate approach is to use TextWriter.Synchronized to wrap StreamWriter.
void Main(string[] args)
{
var rnd = new Random();
var writer = new StreamWriter(#"C:\temp\foo.txt");
var syncedWriter = TextWriter.Synchronized(writer);
var tasks = new List<Func<string>>();
for (int i = 0; i < 1000; i++)
{
int local_i = i; // get a local value, not closure-reference to i
tasks.Add(() =>
{
var delay = rnd.Next(5);
Thread.Sleep(delay);
return local_i.ToString() + " act that that lasted " + delay.ToString();
});
}
Parallel.ForEach(tasks, task =>
{
var value = task();
syncedWriter.WriteLine(value);
});
writer.Dispose();
}
Here are some of the synchronization helper classes
http://referencesource.microsoft.com/#q=Synchronized
System.Collections
static ArrayList Synchronized(ArrayList list)
static IList Synchronized(IList list)
static Hashtable Synchronized(Hashtable table)
static Queue Synchronized(Queue queue)
static SortedList Synchronized(SortedList list)
static Stack Synchronized(Stack stack)
System.Collections.Generic
static IList Synchronized(List list)
System.IO
static Stream Synchronized(Stream stream)
static TextReader Synchronized(TextReader reader)
static TextWriter Synchronized(TextWriter writer)
System.Text.RegularExpressions
static Match Synchronized(Match inner)
static Group Synchronized(Group inner)
It is seems that it isn't problem of Parallelism. It's StringBuilder's problem.
I have replaced:
_streamWriter.WriteLine(Log.ToString());
with:
for (int i = 0; i < Log.Length; i++)
{
_streamWriter.Write(Log[i]);
}
And it worked.
For future reference: http://msdn.microsoft.com/en-us/library/system.text.stringbuilder(v=VS.100).aspx
Memory allocation section.

Exception when trying to show a form created in another (background) thread on .netCF with OAC

In a multi form .NetCF 3.5 application I'm trying create the forms in the background while the user is occupied with the previous form.
We're using Orientation Aware Control in the project
We use a wrapper class (FormController) (please let me know if I'm using the wrong terminology) to keep static references to the different forms in our application. Since we only want to create them once.
At the moment the Forms are created the first time they are used. But since this is a time consuming operation we'd like to do this in the background while the user
Application.Run(new FormController.StartUI());
class FormController{
private static object lockObj = new object();
private static bool secIsLoaded = false;
private static StartForm startForm = new StartForm();
private static SecForm m_SecForm;
static SecForm FormWorkOrderList
{
get
{
CreateSecForm();
return m_SecForm;
}
}
private static void StartUI(){
startForm.Show();
ThreadStart tsSecForm = CreateSecForm;
Thread trSecForm = new Thread(tsSecForm);
trSecForm.Priority = ThreadPriority.BelowNormal;
trSecForm.IsBackground = true;
trSecForm.Start();
return startForm;
}
private static void CreateSecForm()
{
Monitor.Enter(lockObj);
if(!secIsLoaded){
m_SecForm = new SecForm();
secIsLoaded = true;
}
Monitor.Exit(lockObj);
}
private static void GotoSecForm()
{
SecForm.Show();
StartForm.Hide();
}
When I call GotoSecForm() the program throws an excepton on SecForm.Show() with an exection with hResult: 2146233067 and no other valuable information.
The stacktrace of the exception is:
on Microsoft.AGL.Common.MISC.HandleAr(PAL_ERROR ar)
on System.Windows.Forms.Control.SuspendLayout()
on b..ctor(OrientationAwareControl control)
on Clarius.UI.OrientationAwareControl.ApplyResources(CultureInfo cultureInfo, Boolean skipThis)
on Clarius.UI.OrientationAwareControl.ApplyResources()
on Clarius.UI.OrientationAwareControl.OnLoad(EventArgs e)
on Clarius.UI.OrientationAwareControl.c(Object , EventArgs )
on System.Windows.Forms.Form.OnLoad(EventArgs e)
on System.Windows.Forms.Form._SetVisibleNotify(Boolean fVis)
on System.Windows.Forms.Control.set_Visible(Boolean value)
on System.Windows.Forms.Control.Show()
I'm quite qlueless about what's going wrong here. Can anyone help me out?
Or are there some better ways to load the forms in the background?
Let me know if any more information is needed.
You can't create forms (or safely do any manipulation of controls or forms) in background threads. They need to be created on the same thread that the message pump is running on - its just the way that Windows Forms work.
Creating the form itself shouldn't be in itself an expensive task. My advice would be to perform any expensive computations needed to display the form in a background thread, and then pass the result of those computations back to the main message pump in order to create and display the form itself.
(Half way through writing this I realised that this question is about windows mobile, however I'm 99% sure that the above still applies in this situation)

Lock() not effective

I'm trying to lock an object whiel itterating through its elements. The arraylist allThreads of mine is really not locked, because during the execution of the "foreach" I get a exception saying "Collection was modified; enumeration operation may not execute." I thought that was the whole deal with lock?
lock (mApp.allThreads)
{
foreach (Thread t in mApp.allThreads)
if (t.Name == "OpcDAWriter" && t != Thread.CurrentThread)
t.Join();
}
I think you might have misunderstood what lock does for you. It does not prevent other code from manipulating the object that you have taken a lock on. What it does is to prevent one thread from acquiring a long on one object, while another thread is holding the lock.
If you want to prevent one thread from manipulating the collection while another thread is iterating over it, you will need to put both the iterating code, and the manipulating code within lock blocks, locking on the same object.
Simple sample:
class LockDemo
{
private IList<string> _items;
private object _lock = new object();
public LockDemo()
{
_items = new List<string>(new[] { "one", "two", "three" });
}
public void RemoveItem(string item)
{
lock (_lock)
{
_items.Remove(item);
}
}
public void DoSomethingThatIteratesOverTheList()
{
lock (_lock)
{
foreach (var item in _items)
{
// do something with item
}
}
}
}
Notice how all access to the list (except for the constructor in this case) are wrapped in lock blocks that are all locking on the same object. Also note that this object is not the list itself, but an object that is used only for locking purposes. This shows that lock does not lock the object as such, but provides a mechanism to control what parts of the code that may or may not be executed in parallel by different threads.
You are joining into the t thread, so it probably gets removed from mApp.allThreads or something else happens due to the join, thus modifying the collection.
Also, just because you are looking the object, not all other methods could lock on it, the lock only works when all methods accesing the object are locking on it. You could try using an external object as your lock parameter, ie:
private readonly _lock = new object();
[...]
lock(_lock)
{
foreach....
}
but I doubt that will change anything.

Resources