ตามคำถามของคุณ ...
วิธีการส่งผ่านพารามิเตอร์ไปที่ Thread.ThreadStart () วิธีการใน C #?
... และข้อผิดพลาดที่คุณพบคุณจะต้องแก้ไขรหัสของคุณจาก
Thread thread = new Thread(new ThreadStart(download(filename));
ถึง
Thread thread = new Thread(new ThreadStart(download));
thread.Start(filename);
อย่างไรก็ตามคำถามนั้นซับซ้อนกว่าอย่างที่เห็นในตอนแรก
Thread
ระดับปัจจุบัน (4.7.2) ให้หลายก่อสร้างและStart
วิธีการที่มีการทับถม
ตัวสร้างที่เกี่ยวข้องเหล่านี้สำหรับคำถามนี้คือ:
public Thread(ThreadStart start);
และ
public Thread(ParameterizedThreadStart start);
ซึ่งใช้ThreadStart
ผู้รับมอบสิทธิ์หรือParameterizedThreadStart
ผู้รับมอบสิทธิ์
ตัวแทนที่เกี่ยวข้องมีลักษณะดังนี้:
public delegate void ThreadStart();
public delegate void ParameterizedThreadStart(object obj);
เพื่อที่จะเห็นคอนสตรัคเตอร์ที่ถูกต้องที่ใช้ดูเหมือนจะเป็นParameterizedThreadStart
ผู้รับมอบสิทธิ์เพื่อให้วิธีการบางอย่างสอดคล้องกับลายเซ็นที่ระบุของผู้รับมอบสิทธิ์สามารถเริ่มต้นโดยเธรด
ตัวอย่างง่าย ๆ สำหรับการเริ่มต้นThread
เรียนจะเป็น
Thread thread = new Thread(new ParameterizedThreadStart(Work));
หรือเพียงแค่
Thread thread = new Thread(Work);
ลายเซ็นของวิธีการที่สอดคล้องกัน (เรียกWork
ในตัวอย่างนี้) มีลักษณะดังนี้:
private void Work(object data)
{
...
}
สิ่งที่เหลือคือการเริ่มหัวข้อ ทำได้โดยใช้ทั้ง
public void Start();
หรือ
public void Start(object parameter);
ในขณะที่Start()
จะเริ่มเธรดและส่งผ่านnull
ข้อมูลไปยังเมธอดStart(...)
สามารถใช้เพื่อส่งผ่านสิ่งใดก็ตามไปยังWork
เมธอดของเธรด
อย่างไรก็ตามมีปัญหาใหญ่อย่างหนึ่งในวิธีการนี้: ทุกสิ่งที่ผ่านเข้าสู่Work
วิธีการนั้นจะถูกส่งเข้าไปในวัตถุ ซึ่งหมายความว่าภายในWork
วิธีการนั้นจะต้องทำการแปลงกลับไปเป็นประเภทเดิมอีกครั้งเหมือนในตัวอย่างต่อไปนี้:
public static void Main(string[] args)
{
Thread thread = new Thread(Work);
thread.Start("I've got some text");
Console.ReadLine();
}
private static void Work(object data)
{
string message = (string)data; // Wow, this is ugly
Console.WriteLine($"I, the thread write: {message}");
}
การคัดเลือกนักแสดงเป็นสิ่งที่คุณไม่ต้องการทำ
เกิดอะไรขึ้นถ้ามีคนส่งสิ่งอื่นที่ไม่ใช่สตริง ในตอนนี้ดูเหมือนจะเป็นไปไม่ได้ในตอนแรก (เพราะเป็นวิธีการของฉันฉันรู้ว่าฉันทำอะไรหรือวิธีนี้เป็นแบบส่วนตัวใครบางคนควรจะผ่านสิ่งใดไปได้อย่างไร ) คุณอาจจะจบลงด้วยเหตุผลหลายประการ . เนื่องจากบางกรณีอาจไม่เป็นปัญหา ในกรณีเช่นนี้คุณอาจจะจบลงด้วยการInvalidCastException
ที่คุณอาจจะไม่สังเกตเห็นเพราะมันจะยุติเธรด
ในฐานะที่เป็นโซลูชันที่คุณคาดว่าจะได้รับParameterizedThreadStart
มอบหมายทั่วไปเช่นParameterizedThreadStart<T>
ที่T
จะเป็นประเภทของข้อมูลที่คุณต้องการส่งผ่านWork
วิธีการ น่าเสียดายที่บางสิ่งเช่นนี้ไม่มีอยู่ (ยัง?)
อย่างไรก็ตามมีวิธีการแก้ไขที่แนะนำสำหรับปัญหานี้ มันเกี่ยวข้องกับการสร้างคลาสที่มีทั้งข้อมูลที่จะส่งผ่านไปยังเธรดเช่นเดียวกับวิธีการที่แสดงถึงวิธีการของผู้ปฏิบัติงานเช่นนี้:
public class ThreadWithState
{
private string message;
public ThreadWithState(string message)
{
this.message = message;
}
public void Work()
{
Console.WriteLine($"I, the thread write: {this.message}");
}
}
ด้วยวิธีนี้คุณจะเริ่มกระทู้เช่นนี้
ThreadWithState tws = new ThreadWithState("I've got some text");
Thread thread = new Thread(tws.Work);
thread.Start();
ดังนั้นด้วยวิธีนี้คุณหลีกเลี่ยงการแคสต์และมีวิธีที่ปลอดภัยในการให้ข้อมูลกับเธรด ;-)