Создать новый поток, передавая параметры
Я хочу создать поток, а затем передать ему параметры. Но я не знаю, как.
Thread siteDownloader = new Thread(new ParameterizedThreadStart(GetHTML));
Это функция, которую я хочу запустить как новый поток.
static string GetHTML(string siteURL)
{
WebClient webClient = new WebClient();
try
{
string sitePrefix = siteURL.Substring(0, 7);
if (sitePrefix != "http://")
{
siteURL = "http://" + siteURL;
}
}
catch
{
siteURL = "http://" + siteURL;
}
try
{
return webClient.DownloadString(siteURL);
}
catch
{
return "404";
}
}
Ответы
Ответ 1
Ссылаясь на msdn:
public class Work
{
public static void Main()
{
// To start a thread using a shared thread procedure, use
// the class name and method name when you create the
// ParameterizedThreadStart delegate. C# infers the
// appropriate delegate creation syntax:
// new ParameterizedThreadStart(Work.DoWork)
//
Thread newThread = new Thread(Work.DoWork);
// Use the overload of the Start method that has a
// parameter of type Object. You can create an object that
// contains several pieces of data, or you can pass any
// reference type or value type. The following code passes
// the integer value 42.
//
newThread.Start(42);
// To start a thread using an instance method for the thread
// procedure, use the instance variable and method name when
// you create the ParameterizedThreadStart delegate. C# infers
// the appropriate delegate creation syntax:
// new ParameterizedThreadStart(w.DoMoreWork)
//
Work w = new Work();
newThread = new Thread(w.DoMoreWork);
// Pass an object containing data for the thread.
//
newThread.Start("The answer.");
}
public static void DoWork(object data)
{
Console.WriteLine("Static thread procedure. Data='{0}'",
data);
}
public void DoMoreWork(object data)
{
Console.WriteLine("Instance thread procedure. Data='{0}'",
data);
}
}
так как вы можете видеть, что вы создаете метод с object
в качестве параметра и передаете этот параметр методу Start
класса Thread
Ответ 2
Лично я всегда использую захваченные переменные, I.e.
int a = ...
string b = ...
ThreadStart work = delegate {
var result = DoSomethingInteresting(a, b);
// push result somewhere; might involve a UI
// thread switch
};
new Thread(work).Start();
Это означает, что он всегда проверяется на правильность во время сборки, в отличие от передачи объектного параметра.
Ответ 3
Решение Rafal будет работать, но я не уверен, как вы получите от этого возвращаемое значение. Как указывает Мартиньо, параметр ParameterizedThreadStart требует возврата метода недействительным. Вместо этого попробуйте использовать BackgroundWorker.
Назовите это так.
var bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(bw_DoWork);
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bw_RunWorkerCompleted);
bw.RunWorkerAsync(url);
Вот DoWork, в основном модифицированная версия GetHTML.
static void bw_DoWork(object sender, DoWorkEventArgs e)
{
WebClient webClient = new WebClient();
string siteURL = (string)e.Argument;
try
{
string sitePrefix = siteURL.Substring(0, 7);
if(sitePrefix != "http://")
siteURL = "http://" + siteURL;
}
catch
{
siteURL = "http://" + siteURL;
}
try
{
e.Result = webClient.DownloadString(siteURL);
}
catch
{
e.Result = "404";
}
}
Наконец, сделайте что-нибудь подобное в bw_RunWorkerCompleted
static void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
string result;
result = (string)e.Result;
//do something with result
}
Ответ 4
Вы просмотрели документы для ParametrizedThreadStart
? Вам нужен метод, который принимает параметр объекта и ничего не возвращает. Итак, вам нужно будет соответствующим образом изменить свою подпись метода:
static void GetHTML(object data)
{
string siteUrl = (string) data; // cast argument to string
// blah blah
}
И тогда вам нужно выяснить способ использования возвращаемого значения.