幾天前,我開始在我的WPF應用程序中使用任務來實現並行化。我的應用程序需要每5秒執行一些工作。這項工作必須由4個任務並行完成。除此之外,後臺工作人員需要實施以避免在按任務完成工作時凍結UI。我發現了很多例子來理解任務是如何工作的。但是,我找不到任何簡單的例子來理解任務如何與定時器,後臺工作人員和課程鎖定在一起。我根據自己的理解寫了一個簡單的例子。請給我建議我是否正確地做。這樣,我將更好地理解WPF中的多任務處理。我期待着您的回覆。WPF多任務以及計時器和後臺工作人員
namespace timer_and_thread
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
DispatcherTimer TimerObject;
Task[] tasks;
readonly object _countLock = new object();
int[] Summ = new int[10];
int Index = 0;
int ThreadsCounter = 0;
public MainWindow()
{
InitializeComponent();
TimerObject = new DispatcherTimer();
TimerObject.Tick += new EventHandler(timer_Elapsed);
TimerObject.Interval = new TimeSpan(0, 0, 5);
}
// call the method every 5 seconds
private void timer_Elapsed(object sender, EventArgs e)
{
TimerObject.Stop();
// 4 - is the tasks' count
ThreadsCounter = 4;
Index = 0;
tasks = new Task[4];
tasks[0] = Task.Factory.StartNew(() => DoSomeLongWork());
tasks[1] = Task.Factory.StartNew(() => DoSomeLongWork());
tasks[2] = Task.Factory.StartNew(() => DoSomeLongWork());
tasks[3] = Task.Factory.StartNew(() => DoSomeLongWork());
// wait untill all tasks complete
while (ThreadsCounter != 0) ;
TimerObject.Start();
}
private void DoSomeLongWork()
{
while (Index < Summ.Length)
{
// lock the global variable from accessing by multiple threads at a time
int localIndex = Interlocked.Increment(ref Index) - 1;
//I wrote rundom number generation just a an example of doing some calculation and getting some result. It can also be some long calculation.
Random rnd = new Random();
int someResult = rnd.Next(1, 100000);
// lock the global variable (Summ) to give it the result of calculation
lock (_countLock)
{
Summ[localIndex] = someResult;
}
}
Interlocked.Decrement(ref ThreadsCounter);
return;
}
// button by which I start the application working
private void Start_Button_Click_1(object sender, RoutedEventArgs e)
{
TimerObject.Start();
}
}
}
我有2個額外的問題:
我可以使用任務,而不是後臺工作的?
正如我所知,鎖定用於防止線程訪問全局變量。但是,要通過線程訪問UI元素,我應該使用分派器。對?
Application.Current.Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
{
label1.Content = "Some text";
}));
1)是嘗試Task.Factory.StartNew(()=> StartThreads(NULL,NULL));而不是後臺工作人員自己看2)正確:) – sevdalone
感謝您的回答。代碼如何,是否將任務,計時器和BackgroundWorker一起實現? –
關鍵是,後臺工作者什麼都不做。你不需要它來啓動任務,這些任務在自己的線程中運行,無論如何 –