귀하의 질문에 따르면 ...
C #에서 Thread.ThreadStart () 메서드에 매개 변수를 전달하는 방법은 무엇입니까?
... 그리고 오류가 발생하면 코드를 수정해야합니다.
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();
따라서이 방법으로 캐스팅을 피하고 스레드에 데이터를 제공하는 안전한 형식의 방법을 사용하십시오.