Hi everyone,
I've got myself a C# .NET 1.1 application I'm making where a docked
Panel that contains some progress bars etc. is being toggled between
Visible and not. Basically a user drags some photos into the window and
it activates a background thread that shows the panel, does some work,
and hides it again. If this is not in a separate thread, it works! I've
tried doing a manual Update(), and PerformLayout() calls, but nothing
works. The thread work happens, but the panel never shows. I've also
tried Application.DoEvents().

private void itemImages_DragDrop(object sender,
System.Windows.Forms.DragEventArgs e) {
ArrayList formats = new ArrayList(e.Data.GetFormats());

if(formats.Contains(DataFormats.FileDrop)){
//imageImportFiles =
(string[])e.Data.GetData(DataFormats.FileDrop);
imageImportFiles.Clear();
imageImportFiles.AddRange((string[])e.Data.GetData(DataFormats.FileDrop));

imageImportThread = new Thread(new ThreadStart(this.importImages));
imageImportThread.Start();
}
}


private void importImages(){
imageImportPanel.Visible = true;
imageLoadProgress.Maximum = imageImportFiles.Count;
imageLoadProgress.Value = 0;

ArrayList imageFiles = new ArrayList();

foreach(string filePath in imageImportFiles){
importDirectory(filePath, imageFiles);
}

imageLoadProgress.Maximum = imageFiles.Count;
imageLoadProgress.Value = 0;

foreach(string filePath in imageFiles){
string label = getFileName(filePath);
Image img;
int imgId;
ListViewItem item;

imageImportStatus.Text = String.Format("Importing {0}... ({1} of
{2})",
label, imageLoadProgress.Value+1, imageLoadProgress.Maximum);

Application.DoEvents();

try{
img = Image.FromFile(filePath);
}catch(Exception){
continue;
}

imgId = itemImageList.Images.Add(img, Color.Transparent);
item = itemImages.Items.Add(label, imgId);
imageLoadProgress.Value++;
}

imageImportPanel.Visible = false;
}

Re: Multithreaded Panel Visiblility by Andrew

Andrew
Sat Oct 15 14:56:14 CDT 2005

You're not supposed to interact with objects on the ui thread from a
background thread. You should make calls back into the ui thread using a
control's Invoke or BeginInvoke method and interact with the controls from
there. Also, I'd recommend avoiding DoEvents calls since that can lead to
re-entrancy issues, etc. You might want to check a couple of ms articles on
safely marshalling from a background thread to the ui thread.
e.g.
http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/default.aspx
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnforms/html/winforms06112002.asp


<nullmind@gmail.com> wrote in message
news:1129360738.578061.143280@f14g2000cwb.googlegroups.com...
> Hi everyone,
> I've got myself a C# .NET 1.1 application I'm making where a docked
> Panel that contains some progress bars etc. is being toggled between
> Visible and not. Basically a user drags some photos into the window and
> it activates a background thread that shows the panel, does some work,
> and hides it again. If this is not in a separate thread, it works! I've
> tried doing a manual Update(), and PerformLayout() calls, but nothing
> works. The thread work happens, but the panel never shows. I've also
> tried Application.DoEvents().
>
> private void itemImages_DragDrop(object sender,
> System.Windows.Forms.DragEventArgs e) {
> ArrayList formats = new ArrayList(e.Data.GetFormats());
>
> if(formats.Contains(DataFormats.FileDrop)){
> //imageImportFiles =
> (string[])e.Data.GetData(DataFormats.FileDrop);
> imageImportFiles.Clear();
> imageImportFiles.AddRange((string[])e.Data.GetData(DataFormats.FileDrop));
>
> imageImportThread = new Thread(new ThreadStart(this.importImages));
> imageImportThread.Start();
> }
> }
>
>
> private void importImages(){
> imageImportPanel.Visible = true;
> imageLoadProgress.Maximum = imageImportFiles.Count;
> imageLoadProgress.Value = 0;
>
> ArrayList imageFiles = new ArrayList();
>
> foreach(string filePath in imageImportFiles){
> importDirectory(filePath, imageFiles);
> }
>
> imageLoadProgress.Maximum = imageFiles.Count;
> imageLoadProgress.Value = 0;
>
> foreach(string filePath in imageFiles){
> string label = getFileName(filePath);
> Image img;
> int imgId;
> ListViewItem item;
>
> imageImportStatus.Text = String.Format("Importing {0}... ({1} of
> {2})",
> label, imageLoadProgress.Value+1, imageLoadProgress.Maximum);
>
> Application.DoEvents();
>
> try{
> img = Image.FromFile(filePath);
> }catch(Exception){
> continue;
> }
>
> imgId = itemImageList.Images.Add(img, Color.Transparent);
> item = itemImages.Items.Add(label, imgId);
> imageLoadProgress.Value++;
> }
>
> imageImportPanel.Visible = false;
> }
>




Re: Multithreaded Panel Visiblility by Jon

Jon
Sun Oct 16 02:30:14 CDT 2005

<nullmind@gmail.com> wrote:
> I've got myself a C# .NET 1.1 application I'm making where a docked
> Panel that contains some progress bars etc. is being toggled between
> Visible and not. Basically a user drags some photos into the window and
> it activates a background thread that shows the panel, does some work,
> and hides it again. If this is not in a separate thread, it works! I've
> tried doing a manual Update(), and PerformLayout() calls, but nothing
> works. The thread work happens, but the panel never shows. I've also
> tried Application.DoEvents().

<snip>

You need to follow the golden rules of WinForms threading: don't access
the UI on the wrong thread.

See http://www.pobox.com/~skeet/csharp/threads/winforms.shtml

--
Jon Skeet - <skeet@pobox.com>
http://www.pobox.com/~skeet Blog: http://www.msmvps.com/jon.skeet
If replying to the group, please do not mail me too