2012-01-17 2 views
1

Я действительно не понимаю функцию ThreadStart. Может ли кто-нибудь дать простое объяснение?Как вернуть результат из этой темы?

Я хочу вернуть string из функции ThreadStart в то же имя функции, но другой вызов. Как мне это сделать?

Вот мой пример кода:

первого вызова:

thSystem[index] = new Thread(new ThreadStart(StartProcess())); 

второй вызов:

StartProcess(); 

затем

public void StartProcess() 
{ 
    //return string 
} 
+0

Простой веб-поиск показывает несколько достоверных результатов, включая [этот поток MSDN] (http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/c43c0cce-491a-4ddb-9012-69929fab8e5e/) –

+0

Как вы можете вернуть строку, когда ваш метод возвращает void? – Zenwalker

+3

@zenwalker - тип возврата void является обязательным для [делегирования ThreadStart] (http://msdn.microsoft.com/en-us/library/system.threading.threadstart.aspx) –

ответ

0

Что вы должны сделать, это что-то вроде после

public class Work 
{ 
    Work() { }; 

    string WorkString { get; set; } 

    public void DoWork() 
    { 
    WorkString = setString; 
    } 

} 

var newWork = new Work; 
thSystem[index] = new Thread(new ThreadStart(newWork.DoWork())); 


newWork.WorkString; 
+0

, когда я применяю переменную = newWork.WorkString; он возвращает только нулевое значение – user983738

0

Вы также можете сделать это с помощью своего рода государственной переменной и с помощью опции ParameterizedThreadStart делегата:

Используя класс состояния, такие как:

public class ThreadState 
{ 
    public string SomeReturnValue { get; set; } 
} 

и определить вашу обработку резьбы метод, подобный:

public void DoWork(object param) 
{ 
    ThreadState state = param as ThreadState; 

    if (state == null) 
     throw InvalidCastException(String.Format("Unable to cast type {0} to {1}.", param.GetType().Name, typeof(ThreadState).Name)); 

    state.SomeReturnValue = "Success"; 
} 

Вы можете вызвать нить:

thSystem[index] = new Thread(DoWork); 
ThreadState work = new ThreadState(); 
thSystem[index].Start(work); 

А затем получить доступ к возвращаемому значению с:

if(work.SomeReturnValue == "Success") 
    Console.WriteLine(The thread invocation was successful!"); 

Никто из этого кода не был проверен, но должен быть очень близко к рабочему состоянию, как есть.

EDIT: фиксированный параметр типа и включал проверку типа

1

Вы должны рассмотреть вопрос об использовании библиотеки Task Parallel Library, чтобы сделать это, а не использовать потоковую API, это упростит ваш код много. Вы можете дождаться завершения задачи и получить доступ к свойству Result, чтобы получить результат, когда задача завершена.

static string StartProcess() 
{ 
    // do stuff... 
    return "some string"; 
} 

Task<string> myTask = Task.Factory.StartNew<string>(StartProcess); 
myTask.Wait(); // wait for it to complete 
string result = myTask.Result; // get the result 

Лучшим способом сделать это было бы предоставление метода продолжения, который будет выполняться автоматически, когда он будет завершен.

static string StartProcess() 
{ 
    // do stuff... 
    return "some string"; 
} 

// to be executed when the task completes 
static void WhenComplete(Task<string> task) 
{ 
    string result = task.Result; 
    // do something with result 
} 

Task myTask = Task.Factory.StartNew<string>(StartProcess) 
    .ContinueWith(WhenComplete); 
myTask.Wait(); // wait for everything to complete 
+1

Примечание: это .NET 4.0 и выше. –

+0

+1 Определенно это. – Tudor

0

Чтобы ответить на ваш вопрос первый: ThreadStart просто делегат. Это используется для «передачи метода» экземпляру потока. Затем этот метод выполняется в контексте нового потока.

Существует два типа: ThreadStart - это простые методы, не требующие параметров. ParameterizedThreadStart используется, если вы хотите передать аргумент в поток.

Метод потока не может возвращать значения.То, что вы обычно делаете, это определить «объект состояния», который вы передаете в поток, который затем может изменять его содержимое (что, кстати, также является чистым способом предоставления параметров для потока). После того, как поток закончится, вы получите свой результат.

Я знаю, что есть более простые способы, как BackgroundWorker с или Task с, но вы просили специально для Thread с, так что здесь мы идем:

Нам нужен простой объект состояния, который будет содержать результат этого потока:

private class ThreadResult 
{ 
    public string Result; 
} 

Теперь нам нужен метод, который вы хотите позвонить без использования резьбы:

public string PerformSomething() 
{ 
    return "Hello World"; 
} 

Теперь нам нужен метод потока, который будет запускаться в другом потоке. Мы просто вызываем этот метод методом PerformSomething и сохраняем результат в объекте состояния. Обратите внимание, что PerformSomething также будет называться в контексте вызывающего потока - так что вы должны убедиться, что для обработки пользовательского интерфейса обновления правильно и сделать его поточно-(это выходит за рамки данной темы):

public string StartProcess(object state) 
{ 
    ThreadResult result = (ThreadResult)state; 
    result.Result = PerformSomething(); 
} 

Теперь мы начать новую тему и сделать его сделать что-то:

ThreadResult myResult = new ThreadResult(); 
Thread t = new Thread(ParameterizedThreadStart(StartProcess)); 
t.Start(myResult); 

// Wait for the thread to end 
t.Join(); 

// Evaluate the result 
Console.WriteLine(myResult.Result); 

Как это не имеет особого смысла нерест нить, а затем еще заблокировать приложение, чтобы ждать его до конца, мы это немного изменить. Предположим, что вы создаете нить каким-то способом. Затем поток выполнит свою работу и запустит другой метод, когда он будет завершен. Затем вы можете обрабатывать результат асинхронно.

public void SomeMethodThatStartsTheThread() 
{ 
    ThreadResult myResult = new ThreadResult(); 
    Thread t = new Thread(new ParameterizedThreadStart(StartProcess)); 
    t.Start(myResult); 

    // We can do other work while the thread is running 
} 

public string StartProcess(object state) 
{ 
    ThreadResult result = (ThreadResult)state; 
    result.Result = PerformSomething(); 

    ThreadIsDone(result); 
} 

public void ThreadIsDone(ThreadResult result) 
{ 
    // Do stuff you want to do when the thread is done 
} 

Пожалуйста, обратите внимание, что ThreadIsDone также называют в контексте потока вы порождал в SomeMethodThatStartsTheThread.

Смежные вопросы