sourcecode

Thread에서 ThreadStart 메서드에 매개 변수를 전달하는 방법은 무엇입니까?

codebag 2023. 5. 8. 22:13
반응형

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 thread = new Thread(download);
    thread.Start(filename);

그러나 '다운로드' 메서드는 여전히 매개 변수로 문자열을 사용하지 않고 개체를 사용해야 합니다.메소드 본문의 문자열에 캐스팅할 수 있습니다.

매개 변수를 사용하는 스레드 메서드에 대해 대리자를 사용하려고 합니다. (또는 실제로는 전혀 없음)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();

추가로

    Thread thread = new Thread(delegate() { download(i); });
    thread.Start();

저는 당신에게 파일이라는 다른 수업을 권하고 싶습니다.

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);

클래스에서 스레드 함수(다운로드)와 필요한 매개 변수(파일 이름)를 캡슐화하고 스레드 시작 대리자를 사용하여 스레드 함수를 실행할 수 있습니다.

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);

이것은 어떻습니까: (아니면 이렇게 사용해도 괜찮습니까?)

var test = "Hello";
new Thread(new ThreadStart(() =>
{
    try
    {
        //Staff to do
        Console.WriteLine(test);
    }
    catch (Exception ex)
    {
        throw;
    }
})).Start();

당신 질문에 따르면...

매개 변수를 스레드에 전달하는 방법.C#의 ThreadStart() 메서드?

...그리고 발생한 오류는 코드를 수정해야 합니다.

Thread thread = new Thread(new ThreadStart(download(filename));

로.

Thread thread = new Thread(new ThreadStart(download));
thread.Start(filename);



하지만, 처음에 보이는 것처럼 질문은 더 복잡합니다.

현재 클래스(4.7.2)는 오버로드가 있는 여러 생성자와 메서드를 제공합니다.

이 질문과 관련된 생성자는 다음과 같습니다.

public Thread(ThreadStart start);

그리고.

public Thread(ParameterizedThreadStart start);

대리인이나 대리인 중 한 명이 필요합니다.

해당 딜러의 모습은 다음과 같습니다.

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}");
}



캐스팅은 일반적으로 원하지 않는 작업입니다.

만약 누군가가 끈이 아닌 다른 것을 건네준다면요?처음에는 이것이 불가능해 보이기 때문에(나는 방법이기 때문에, 나는 내가 무엇을 하는지 알고 있다, 또는방법은 사적인 이다, 어떻게 누군가가 그것에게 무언가를 전달할 수 있어야 하는가?) 당신은 다양한 이유로 인해 정확하게 그 사례로 끝날 수도 있습니다.어떤 경우는 문제가 되지 않을 수도 있기 때문에 다른 경우는 문제가 됩니다.이러한 경우에는 스레드가 단순히 종료되기 때문에 눈치채지 못할 수도 있습니다.

솔루션으로 일반 제품을 구입할 수 있습니다.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

반응형