|
|
|
Win App รื้อปัญหาที่คาใจมานานครับ เกี่ยวกับ Threading และ task ครับ |
|
|
|
|
|
|
|
|
|
|
|
|
Date :
2019-09-19 11:02:37 |
By :
mr.win |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
backgroundworker
parallel thread
|
|
|
|
|
Date :
2019-09-25 00:08:58 |
By :
bigsuntat |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Code (C#)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace TaskExam
{
class Program
{
static int runningFolder = -1;
static List<string> folderList;
static int MaxTask = 5;
static Task[] workerTasks;
static void Main(string[] args)
{
var rootFolder = @"D:\A_BOOK";
folderList = Directory.GetDirectories(rootFolder, "*", SearchOption.AllDirectories).ToList();
if (folderList.Count == 0) return;
if (folderList.Count > MaxTask)
workerTasks = new Task[MaxTask];
else
{
MaxTask = folderList.Count;
workerTasks = new Task[MaxTask];
}
var rnd = new Random();
Action<object> workAction = (object path) =>
{
// Thread.Sleep(rnd.Next(500, 1000));
//Console.WriteLine("Task={0}, obj={1}, Thread={2}",
//Task.CurrentId, path,
//Thread.CurrentThread.ManagedThreadId);
var files = Directory.GetFiles((string)path, "*.*", System.IO.SearchOption.TopDirectoryOnly).ToList();
foreach (string s in files)
{
Console.WriteLine("Task#{0}: {1}", Task.CurrentId, s);
}
};
for (int n=0;n<MaxTask;n++)
{
workerTasks[n] = new Task(workAction, GetAvailFolder());
workerTasks[n].Start();
}
int taskNo = Task.WaitAny(workerTasks);
while (taskNo >= 0)
{
string path = GetAvailFolder();
if (string.IsNullOrEmpty(path)) break;
workerTasks[taskNo] = new Task(workAction, path);
workerTasks[taskNo].Start();
taskNo = Task.WaitAny(workerTasks);
}
Task.WaitAll(workerTasks);
Console.Read();
}
static string GetAvailFolder()
{
string folder = string.Empty;
lock (folderList)
{
if (runningFolder < folderList.Count - 1)
{
runningFolder++;
folder = folderList[runningFolder];
}
}
return folder;
}
}
}
|
|
|
|
|
Date :
2019-09-28 13:21:39 |
By :
watcharop |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Date :
2019-09-28 13:23:36 |
By :
watcharop |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
จะว่าไป มันจะเร็วกว่าการ Copy ไฟล์ แบบโค้ดไม่แยก Thread เป็นหลายๆ Thread อย่างมีนัยยะสำคัญจริงๆ เหรอ?
|
ประวัติการแก้ไข 2019-09-29 12:35:13
|
|
|
|
Date :
2019-09-29 12:34:21 |
By :
watcharop |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ตอบความคิดเห็นที่ : 8 เขียนโดย : watcharop เมื่อวันที่ 2019-09-29 12:34:21
รายละเอียดของการตอบ ::
มาอัพเดทข้อมูลครับ
หลังจากที่ลองๆ ทำดู
ปรากฏว่า ใน Console จะไม่ค่อยมีปัญหาครับ
แต่ถ้าทำบนฟอร์มจะมีปัญหาครับ
Code (C#)
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
int runningFolder = -1;
List<string> folderList;
int MaxTask = 10;
Task[] workerTasks;
private void Form2_Load(object sender, EventArgs e)
{
new Task(Run).Start();
}
void Run()
{
var rootFolder = @"F:\SongTOR";
folderList = Directory.GetDirectories(rootFolder, "*", SearchOption.AllDirectories).ToList();
if (folderList.Count == 0) return;
if (folderList.Count > MaxTask)
workerTasks = new Task[MaxTask];
else
{
MaxTask = folderList.Count;
workerTasks = new Task[MaxTask];
}
Action<object> workAction = (object path) =>
{
if ((string)path != "")
{
var files = Directory.GetFiles((string)path, "*.*", System.IO.SearchOption.TopDirectoryOnly).ToList();
foreach (string s in files)
{
richTextBox1.Invoke(new Action(() => richTextBox1.Text += string.Format("Task#{0}: {1}\n", Task.CurrentId, s)));
}
}
};
/* for (int n = 0; n < MaxTask; n++)
{
workerTasks[n] = new Task(workAction, GetAvailFolder());
workerTasks[n].Start();
}*/
// int taskNo = Task.WaitAny(workerTasks);
/* while (taskNo >= 0)
{
string path = GetAvailFolder();
if (string.IsNullOrEmpty(path)) break;
workerTasks[taskNo] = new Task(workAction, path);
workerTasks[taskNo].Start();
taskNo = Task.WaitAny(workerTasks);
}*/
int i = 0;
do
{
for (int n = 0; n < MaxTask; n++)
{
workerTasks[n] = new Task(workAction, GetAvailFolder());
workerTasks[n].Start();
}
Task.WaitAll(workerTasks);
System.Threading.Thread.Sleep(1000);
richTextBox1.Invoke(new Action(() => richTextBox1.Text += " Complete.. \n"));
i += MaxTask;
} while(i< folderList.Count);
Console.Read();
}
string GetAvailFolder()
{
string folder = string.Empty;
lock (folderList)
{
if (runningFolder < folderList.Count - 1)
{
runningFolder++;
folder = folderList[runningFolder];
}
}
return folder;
}
}
คือเวลา รันแล้วมันจะค้างจนกว่าจะรันเสร็จ ครับ
ปล. ผมให้ รัน จนครบ 10 Task แล้วพักซัก 1 วิ จากนั้นก็รันต่อไปอีก 10 Task ไปเรื่อยๆ ครับ
มันรันทีละ 10 ก็จริง แต่ ค้าง จนไม่สามารถขยับหน้าฟอร์มได้เลยครับ
|
ประวัติการแก้ไข 2019-09-30 16:24:42
|
|
|
|
Date :
2019-09-30 16:22:25 |
By :
lamaka.tor |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ลองใช้ richTextBox1.AppendText(newtext)
แทน richTextBox1.Text += newtext
|
|
|
|
|
Date :
2019-09-30 17:49:11 |
By :
watcharop |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Load balance : Server 01
|