My application has 2 threads - the main UI thread, and another thread.
The application collects a List of file names on the separate thread. I then want this list to be displayed in my GUI. The program works as desired until the thread completes. It results in the following error
"The calling thread must be STA, because many UI components require this."
The following code is run, and as you can see it takes 2 Action Parameters - one for AddCurrentFile and one called Complete. During the duplication.GetDuplicateList()
it invokes the 2 methods.
this._duplicatesThread = new Thread(() =>
{
try
{
duplication.GetDuplicateList(new Action<string>(AddCurrentFile), new Action<List<Duplicate>>(Complete));
CreateParent();
}
catch (Exception ex)
{
string s = ex.ToString();
throw;
}
});
The AddCurrentFile provides a value to my property, and using the INotifyProperty my GUI updates as desired:
private void Complete(List<Duplicate> duplicateList)
{
this._duplicateList = duplicateList;
}
The issue is when I called the CreateParent() as this creates a new UserControl - I then get The calling thread must be STA, because many UI components require this.
But this occurs during the constructor of the UserControl. The following code is where it fails
private void CreateParent()
{
ObservableCollection<DuplicateControl> parent = new ObservableCollection<DuplicateControl>();
foreach (var duplicate in this._duplicateList)
{
DuplicateControl ic = new DuplicateControl();//This fails as soon as I enter the constructor. The DuplicateControl uses the UserControl as a base class
parent.Add(ic);
}
this.ParentDuplicate = parent;
}
So, to appease the thread, within the CreateParent() method I added this._duplicatesThread.Join;
However, I think (and please do correct/agree with me) what is happening at this point is because I'm joining within the thread, it's effectively cancelling the non-UI thread, therefore stopping at that point of it's process! As such, it never executes the line after this._duplicatesThread.Join;
Now, I'm hoping this isn't better asked at Programmers, but, I get the feeling the issue here is more of my design than the code (although I'd be delighted to know that both the pattern and my code is rubbish he he).
My question is, since I can't do this via the new Thread (as it's not a UI thread), what do I need to do? It's almost as if I need a delegate like NewThread.FinishedExecuting += DoThisThing()