Thread에서 ThreadStart 메소드에 매개 변수를 전달하는 방법은 무엇입니까?
Thread.ThreadStart()
C #에서 메서드에 매개 변수를 전달하는 방법은 무엇입니까?
'다운로드'라는 메소드가 있다고 가정하십시오.
public void download(string filename)
{
// download code
}
이제 기본 메소드에서 하나의 스레드를 작성했습니다.
Thread thread = new Thread(new ThreadStart(download(filename));
오류 메소드 유형이 예상됩니다.
매개 변수가 ThreadStart
있는 대상 메소드로 매개 변수를 전달하는 방법은 무엇입니까?
가장 간단한 것은
string filename = ...
Thread thread = new Thread(() => download(filename));
thread.Start();
이것의 장점 ParameterizedThreadStart
은 여러 매개 변수를 전달할 수 있으며 object
항상 캐스팅하지 않아도 컴파일 타임을 확인할 수 있다는 것입니다.
이 예를보십시오 :
public void RunWorker()
{
Thread newThread = new Thread(WorkerMethod);
newThread.Start(new Parameter());
}
public void WorkerMethod(object parameterObj)
{
var parameter = (Parameter)parameterObj;
// do your job!
}
먼저 대리자를 작업자 메서드에 전달하여 스레드를 만든 다음 개체를 매개 변수로 사용하는 Thread.Start 메서드로 시작합니다.
따라서 귀하의 경우 다음과 같이 사용해야합니다.
Thread thread = new Thread(download);
thread.Start(filename);
그러나 '다운로드'방법 은 매개 변수로 문자열이 아닌 객체 를 가져와야 합니다 . 메소드 본문에서 문자열로 캐스트 할 수 있습니다.
ParameterizedThreadStart
매개 변수를 취하는 스레드 메소드에 대리자 를 사용하려고합니다 . (또는 실제로는 아무것도 없으며 Thread
생성자가 추론 하도록하십시오 .)
사용법 예 :
var thread = new Thread(new ParameterizedThreadStart(download));
//var thread = new Thread(download); // equivalent
thread.Start(filename)
당신은 또한 delegate
좋아할 수 있습니다 ...
ThreadStart ts = delegate
{
bool moreWork = DoWork("param1", "param2", "param3");
if (moreWork)
{
DoMoreWork("param1", "param2");
}
};
new Thread(ts).Start();
File이라는 다른 클래스를 사용하는 것이 좋습니다.
public class File
{
private string filename;
public File(string filename)
{
this.filename= filename;
}
public void download()
{
// download code using filename
}
}
스레드 생성 코드에서 새 파일을 인스턴스화합니다.
string filename = "my_file_name";
myFile = new File(filename);
ThreadStart threadDelegate = new ThreadStart(myFile.download);
Thread newThread = new Thread(threadDelegate);
스레드 함수 (다운로드) 및 필요한 매개 변수 (파일 이름)를 클래스에 캡슐화하고 ThreadStart 대리자를 사용하여 스레드 함수를 실행할 수 있습니다.
public class Download
{
string _filename;
Download(string filename)
{
_filename = filename;
}
public void download(string filename)
{
//download code
}
}
Download = new Download(filename);
Thread thread = new Thread(new ThreadStart(Download.download);
추가로
Thread thread = new Thread(delegate() { download(i); });
thread.Start();
이건 어떻습니까?
var test = "Hello";
new Thread(new ThreadStart(() =>
{
try
{
//Staff to do
Console.WriteLine(test);
}
catch (Exception ex)
{
throw;
}
})).Start();
귀하의 질문에 따르면 ...
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();
따라서이 방법으로 캐스팅을 피하고 스레드에 데이터를 제공하는 안전한 형식의 방법을 사용하십시오.
여기 완벽한 방법이 있습니다 ...
private void func_trd(String sender)
{
try
{
imgh.LoadImages_R_Randomiz(this, "01", groupBox, randomizerB.Value); // normal code
ThreadStart ts = delegate
{
ExecuteInForeground(sender);
};
Thread nt = new Thread(ts);
nt.IsBackground = true;
nt.Start();
}
catch (Exception)
{
}
}
private void ExecuteInForeground(string name)
{
//whatever ur function
MessageBox.Show(name);
}
참고 URL : https://stackoverflow.com/questions/3360555/how-to-pass-parameters-to-threadstart-method-in-thread
'Programing' 카테고리의 다른 글
'9.61'을 '9:61'로 변환하기 위해 JavaScript에서 string replace를 어떻게 수행합니까? (0) | 2020.03.25 |
---|---|
Java 메소드를 선언하거나 더 이상 사용되지 않는 것으로 표시하는 방법은 무엇입니까? (0) | 2020.03.25 |
git / GitHub의 기록에서 폴더와 그 내용을 제거하십시오 (0) | 2020.03.25 |
EC2 인스턴스에는 퍼블릭 DNS가 없습니다 (0) | 2020.03.25 |
JavaScript로 이미지의 실제 너비와 높이를 얻으시겠습니까? (0) | 2020.03.25 |