What I'm trying to achieve is simple. I have a dynamic timer (one that can be changed by the user) which calls on background worker to go and fetch the user's external IP address. The combination of Timer
and BackgroundWorker
is causing some problems. Here's the code:
namespace IPdevices
{
/// <summary>
/// Interaction logic for Main.xaml
/// </summary>
public partial class Main : Window
{
private readonly BackgroundWorker worker;
private IPret iprep;
private Timer timer;
public Main(Client client)
{
InitializeComponent();
iprep = new IPret();
startClock();
worker = new BackgroundWorker();
worker.DoWork += worker_DoWork;
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.WorkerReportsProgress = true;
worker.ProgressChanged += worker_ProgressChanged;
}
private void worker_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
ipAdd.Content = e.UserState;
}
private void startClock()
{
timer = new Timer();
timer.Interval = 2000;
timer.Elapsed += new ElapsedEventHandler(clockTimer_Tick);
timer.Start();
}
private void clockTimer_Tick(object sender, ElapsedEventArgs e)
{
timer.Stop();
worker.RunWorkerAsync();
}
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
Console.WriteLine("Checking ip");
iprep.refresh();
worker.ReportProgress(0, iprep.getExternalIp());
Console.WriteLine("Found ip");
}
private void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
timer.Start();
}
}
}
Essentially, once the timer fires, I wish to fetch the ip address and output on a label in the application. However, I get an exception in the ProgressChanged
method saying that it can't be changed because another thread owns it. Which thread is that? Is it the iprep
that is owned by another thread? In fact, RunWorkerCompleted
never gets fired. I'm having trouble understanding which threads own what and how objects are locked...Any insight would be appreciated.