I have two functions named ChangeText() & ChangeColor(), the first function called ChangeText who will loading a large number of data into memory, it will cost a lot of time, So I run it asynchorously; the other one is called ChangeColor who will change the button’s color when data loading ok, so there is an order to run these two functions: ChangeText first and ChangeColor second. here is my code:
using System;
using System.Text;
using System.Windows;
using System.Windows.Media;
using System.Threading;
using System.IO;
namespace ThreadSynchorous
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
asyncInvoke = new AsyncInvoke();
}
AsyncInvoke asyncInvoke;
EventWaitHandle waitMeHandle = new EventWaitHandle(false,EventResetMode.ManualReset);
private void button1_Click(object sender, RoutedEventArgs e)
{
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
{
asyncInvoke.BeginAsync(ChangeText);
}), null);
ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object state)
{
asyncInvoke.BeginAsync(ChangeColor);
}), null);
label1.Content += " \r\n-------------------------\r\n";
}
private bool ChangeText()
{
waitMeHandle.Reset();
this.button1.Dispatcher.Invoke(new Func<bool>(delegate()
{
string filename = @"C:\EXO.txt";
using (StreamReader sr = new StreamReader(filename, Encoding.Default))
{
string result;
while ((result = sr.ReadLine()) != null)
{
//here perform action
}
}
label1.Dispatcher.Invoke(new Func<bool>(delegate
{
label1.Content += "Loading finish!(Thread.CurrentThreadName="+Thread.CurrentThread.ManagedThreadId.ToString()+") ";
waitMeHandle.Set();
return true;
}));
waitMeHandle.Set();
return true;
}));
waitMeHandle.Set();
return true;
}
private bool ChangeColor()
{
waitMeHandle.WaitOne();
this.button1.Dispatcher.Invoke(new Func<bool>(delegate()
{
this.button1.Background = Brushes.Red;
label1.Dispatcher.Invoke(new Func<bool>(delegate()
{
label1.Content += "Coloring finish!(Thread.CurrentThreadName="+Thread.CurrentThread.ManagedThreadId+") ";
return true;
}));
return true;
}));
return true;
}
}
}
here is the class of AsyncInvoke:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ThreadSynchorous
{
public class AsyncInvoke
{
public void BeginAsync(Func<bool> MyFunction)
{
Func<bool> func = new Func<bool>(MyFunction);
IAsyncResult iar = func.BeginInvoke(new AsyncCallback(EndAsync), func);
}
public void EndAsync(IAsyncResult iar)
{
Func<bool> func = (Func<bool>)iar.AsyncState;
func.EndInvoke(iar);
}
}
}
I planed to use EventWaitHandle to sync these two functions, but the result is that these two function will still running in a mess order: sometimes ChangeText() function first, sometimes ChangeColor() first. I just so confused.
And also, I use ThreadPool to start these two function, but why I got the same threadID like below:
Loading finish!(Thread.CurrentThreadName=10) Coloring finish!(Thread.CurrentThreadName=10)
I thought that the Thread.CurrentThreadName will be different because I use the threadpool!!! why? thx for your answer.
See code snippet above -it should explain you a bit. And of course, you’ve got same thread name because you dispatch label delegate to UI thread – that’s the primary reason you shouldn’t do any lengthy operations there like you did initially