Multi-Threading ב-C# - תכנות - HWzone פורומים
עבור לתוכן
  • צור חשבון

Multi-Threading ב-C#


gshhar

Recommended Posts

יש לי תרגיל שבו היוזר אמור להכניס PATH ויפתח TASK שיביא את כל הקבצים באותו ה-PATH, כל PATH שהיוזר יכניס יפתח TASK חדש.

קודם כל רשמתי CLASS שסורקת רקורסיבית את כל ה-PATH ומביאה את כל הקבצים ותוך SortedDictionary אבל עניין ה-TASK עושה לי בעיות, אני לא ממש הצלחתי ליצור אחד והוא מבקש ממני (ב-MAIN) את שם המתודה.

זה ה-CLASS שלי:


public class recursion
{
SortedDictionary<string, FileInfo> mAllFilesWithinPath;


public recursion()
{
mAllFilesWithinPath = new SortedDictionary<string, FileInfo>();
}


public SortedDictionary<string, FileInfo> getDirsFiles(object d)
{
List<string> allFiles = new List<string>();
FileInfo[] files;
files = (d as DirectoryInfo).GetFiles("*.*");


foreach (FileInfo file in files)
{
string filePath = file.FullName;


mAllFilesWithinPath.Add(filePath, file);
}


DirectoryInfo[] dirs = (d as DirectoryInfo).GetDirectories();


foreach (DirectoryInfo dir in dirs)
{
getDirsFiles(dir);
}


return mAllFilesWithinPath;
}
}

זה ה-MAIN:


recursion rec = new recursion();
DirectoryInfo dir = new DirectoryInfo(@"D:\Downloads\Albums");
SortedDictionary<string, FileInfo> files = rec.getDirsFiles(dir);

Console.Write("enter path: ");


Task getFilesTask = new Task(new Action(rec.getDirsFiles(dir)));


string path = Console.ReadLine();


Console.ReadLine();

קישור לתוכן
שתף באתרים אחרים

כאמור, אתה צריך להעביר ל-Task פונקציה שלא מקבלת פרמטרים. יש כמה דרכים לעשות את זה:

1. להגדיר פונקציה כזו, ולהעביר אותה (לא להעביר קריאה לפונקציה, אלא את הפונקציה עצמה, כלומר בלי סוגריים).

2. להשתמש בפונקציה אנונימית.

3. להשתמש בלמבדא.

הדרך הכי פשוטה היא להשתמש בלמבדא.

קישור לתוכן
שתף באתרים אחרים

בהודעה הקודמת בדיוק הסברתי לך שאתה יכול להשתמש גם ב-delegate וגם ב-lambda. אפילו נתתי לך לינק שמסביר מה זה ביטוי למבדא. ספציפית, כל ביטוי למבדא הוא סוג של delegate, ולכן כל פונקציה שמקבלת delegate גם יכולה לקבל lambda מאותו סוג.

הבנאי של Task מצפה לקבל Action, שזה delegate שלא מקבל פרמטרים. אז אתה צריך להעביר לה פונקציה שלא מקבלת פרמטרים.

קישור לתוכן
שתף באתרים אחרים

אחרי שעשיתי getFilesTask.Start(); הוא לא נכנס למתודה

MAIN:


Console.Write("enter path: ");
string path = Console.ReadLine();
DirectoryInfo dir = new DirectoryInfo(path);
recursion rec = new recursion();
Task getFilesTask = new Task(() => rec.getDirsFiles(dir));
getFilesTask.Start();

CLASS:


public class recursion
{
SortedDictionary<string, FileInfo> mAllFilesWithinPath;


public recursion()
{
mAllFilesWithinPath = new SortedDictionary<string, FileInfo>();
}


public SortedDictionary<string, FileInfo> getDirsFiles(DirectoryInfo d)
{
List<string> allFiles = new List<string>();
FileInfo[] files;
files = d.GetFiles("*.*");


foreach (FileInfo file in files)
{
string filePath = file.FullName;


mAllFilesWithinPath.Add(filePath, file);
}


DirectoryInfo[] dirs = d.GetDirectories();


foreach (DirectoryInfo dir in dirs)
{
getDirsFiles(dir);
}


return mAllFilesWithinPath;
}
}

קישור לתוכן
שתף באתרים אחרים

האם זהו כל ה-Main? כלומר, אחרי getFilesTask.Start אין עוד קוד?

אז התכנית שלך תיגמר לפני שה-Task תספיק לרוץ בכלל.

אתה צריך לדאוג לחכות שה-Task יסתיים (באמצעות Task.Wait).

נ.ב. אם אתה יוצר Task ומיד מריץ אותו, אתה יכול לעשות את זה בפקודה אחת: Task.Factory.StartNew

קישור לתוכן
שתף באתרים אחרים

תודה.

אם אני עושה את כל הקליטת PATH מהיוזר בלולאה של WHILE (למשל כל זמן שה-INPUT שונה מאפס) אז כל PATH מפעיל TASK חדש ומחזיר את כל הקבצים מאותו ה-PATH ?

כרגע זה ה-MAIN שלי:


static void Main(string[] args)
{
Console.Write("enter path: ");
string path = Console.ReadLine();

while (path != "0")
{
recursion rec = new recursion(path);
SortedDictionary<string, FileInfo> file = rec.GetFiles(new DirectoryInfo(path));
Task getFilesTask = new Task(() => rec.GetFiles(new DirectoryInfo(path)));
getFilesTask.Start();
getFilesTask.Wait();
path = Console.ReadLine();
getFilesTask = new Task(() => rec.GetFiles(new DirectoryInfo(path)));
}


Console.ReadLine();
}

האם אחרי כל פעם שאני מקבל מהיוזר PATH נפתח לי TASK במקביל ?

קישור לתוכן
שתף באתרים אחרים

עוד שאלה קטנה:

זה ה-MAIM שלי:

    static void Main(string[] args)
{
Console.Write("enter path: ");
string path = Console.ReadLine();


while (path!="0")
{
try
{


recursion rec = new recursion(path);
Task<SortedDictionary<string, FileInfo>> getAllFilesTask = new Task<SortedDictionary<string, FileInfo>>(() => rec.GetFiles(new DirectoryInfo(path)));
getAllFilesTask.Start();


Console.Write("enter word to search or bypass by pressing *: ");
string word = Console.ReadLine();


if (word != "*")
{
Task fineWordTask = new Task(() => rec.FindMatchingNames(word));
fineWordTask.Start();
fineWordTask.Wait();
}


Console.Write("enter path: ");
path = Console.ReadLine();


}
catch (DirectoryNotFoundException)
{
Console.WriteLine("path not found, please try again!");
break;
}
}


Console.ReadLine();
}

כפי שאתם רואים יש לי שם 2 TASK'ים

1 - getAllFilesTask - אחד מקבל מהיוזר PATH ומכניס לרשימה את כל הקבצים מה-PATH

2- fineWordTask - השני מקבל מהיוזר מילה מסויימת ומחפש את המילה או חלק ממנה ברשימה שה-TASK הראשון יצר ומדפיס את התוצאות שם נתקבלו

כרגע אחרי כל פעם שאני מכניס PATH ואת המילה לחיפוש הוא יש מדפיס לי את זה (ההדפסה נמצאת במתודה )

איך אני עושה שרק אחרי שאני אצא החוצה מה-MAIN יוצגו לי כל הקבצים מכל ה-TASK'ים ? ולא אחרי כל חיפוש וחיפוש ?

קישור לתוכן
שתף באתרים אחרים

ארכיון

דיון זה הועבר לארכיון ולא ניתן להוסיף בו תגובות חדשות.

×
  • צור חדש...