|
-
December 15th, 2011, 03:40 PM
#1
using Thread, BackgroundWorker, and DoEvents
I wrote some test code to try and understand the differences between 3 ways of doing background tasks while trying to update the UI in a reasonable fashion. What I did was to create a menu to select 1 of 3 ways to run the task. The task is put 'Please Wait' on the UI, go off and run a task to list all the removable drives on my system, then when done, erase the 'Please Wait'.
Method 1 - I created a dummy DoEvents that basically tells the UI to update. that works.
Method 2 - I created a Thread that calls the Get_Removable_Drives method. It gets the infamous 'Calling thread must be a STA thread' exception.
Method 3 - I created a BackgroundWorker that calls the Get_Removable_Drives method. It also gets the infamous 'Calling thread must be a STA thread' exception.
However, in both the exception errors, there is no attempt to update the UI. It is crashing at the entrance to the RemovableDrives window.
Can someone look at this code and tell me how to organize my code or what to add to make all 3 selections work? I put the WPF code in just in case someone wanted to actually try it. Not to bore you with all the details.
Thanks.
Sutton
Window x:Class="Test.TestMenu"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" WindowState="Normal" ResizeMode="NoResize" WindowStartupLocation="CenterScreen" SizeToContent="WidthAndHeight">
<Grid>
<Button Content="Select" Height="23" HorizontalAlignment="Left" Margin="0,50,0,0" Name="Select" VerticalAlignment="Top" Width="75" Click="Select_Click" />
<RadioButton Content="Test #1 (DoEvents)" Height="16" HorizontalAlignment="Left" Margin="4,0,0,0" Name="Test1" VerticalAlignment="Top" />
<RadioButton Content="Test #2 (Thread)" Height="16" HorizontalAlignment="Left" Margin="4,15,0,0" Name="Test2" VerticalAlignment="Top" />
<RadioButton Content="Test #3 (BackgroundWorker)" Height="16" HorizontalAlignment="Left" Margin="4,30,0,0" Name="Test3" VerticalAlignment="Top" />
<TextBlock Name="TBTestStatus" Text="Please Wait..." Visibility="Hidden" Height="15" HorizontalAlignment="Left" Margin="100,58,0,0" VerticalAlignment="Top" Width="70" />
</Grid>
</Window>
<Window x:Class="Test.RemovableDrives"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Select Removable Drive" Height="96" Width="222" ResizeMode="NoResize" WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterScreen">
<Grid>
<ComboBox Height="23" Name="CBDrives" HorizontalAlignment="Left" VerticalAlignment="Top" Width="200" >
</ComboBox>
<Button Content="Select" Height="23" HorizontalAlignment="Left" Margin="0,35,0,0" Name="SelectButton" VerticalAlignment="Top" Width="75" />
</Grid>
</Window>
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Windows;
using System.Windows.Media;
using System.Windows.Threading;
namespace Test
{
public partial class RemovableDrives : Window
{
public RemovableDrives()
{
InitializeComponent();
List_Removable_Drives();
}
void List_Removable_Drives()
{
List<Removable_Drive_Entry> ListRemovableDrives = new List<Removable_Drive_Entry>();
foreach (DriveInfo d in DriveInfo.GetDrives())
{
if (d.IsReady == true && d.DriveType == DriveType.Removable &&
d.DriveFormat == "FAT32")
{
ListRemovableDrives.Add(new Removable_Drive_Entry()
{
Drive = d.Name + " ",
Volume = d.VolumeLabel
});
}
}
CBDrives.ItemsSource = ListRemovableDrives;
}
public class Removable_Drive_Entry
{
public string Drive { get; set; }
public string Volume { get; set; }
}
}
public partial class TestMenu : Window
{
private delegate void EmptyDelegate();
public TestMenu()
{
InitializeComponent();
}
public static void DoEvents()
{
Dispatcher.CurrentDispatcher.Invoke(DispatcherPriority.Background,new EmptyDelegate(delegate{}));
}
void Select_Click(object sender, RoutedEventArgs e)
{
if (Test1.IsChecked == true) // DoEvents
{
TBTestStatus.Foreground = Brushes.Red;
TBTestStatus.Visibility = Visibility.Visible;
DoEvents();
Get_Removable_Drives1();
}
if (Test2.IsChecked == true) // Thread
{
TBTestStatus.Foreground = Brushes.Red;
TBTestStatus.Visibility = Visibility.Visible;
DoEvents();
Thread t = new Thread(Get_Removable_Drives2);
t.Start();
while (t.ThreadState == ThreadState.Running);
TBTestStatus.Visibility = Visibility.Hidden;
}
if (Test3.IsChecked == true) // BackgroundWorker
{
TBTestStatus.Foreground = Brushes.Red;
TBTestStatus.Visibility = Visibility.Visible;
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += Get_Removable_Drives3;
bw.RunWorkerCompleted += BW_RunWorkerCompleted;
bw.RunWorkerAsync();
}
}
void BW_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
TBTestStatus.Visibility = Visibility.Hidden;
}
void Get_Removable_Drives1()
{
RemovableDrives RDwindow = new RemovableDrives();
TBTestStatus.Visibility = Visibility.Hidden;
RDwindow.ShowDialog();
}
void Get_Removable_Drives2()
{
RemovableDrives RDwindow = new RemovableDrives();
RDwindow.ShowDialog();
}
void Get_Removable_Drives3(object sender, DoWorkEventArgs e)
{
RemovableDrives RDwindow = new RemovableDrives();
RDwindow.ShowDialog();
}
}
}
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|