我有一个在一个事件上调用的方法,它给我提供了两个变量varA,varB(两个字符串)。这个方法经常被新信息调用,因此我创建了一个单独的方法来接受这两个参数。我想在一个线程中运行此方法,但是已经解决了Thread.Start不接受参数的问题。
我尝试了一些假设的方法,但到目前为止还没有运气..我认为最好的办法是创建一个单独的类,并在那里处理..但是我有一个List,我将数据插入
,当单独的类试图访问该列表时,它会死路一条。有人可以帮助我吗?
答案 0 :(得分:4)
一个简单的解决方案......
这会将varA,varB打印到控制台。
new RunTask<string, string>("varA", "varB").StartThread();
public class RunTask<TA, TB>
{
public TA VarA { get; private set; }
public TB VarB { get; private set; }
public RunTask(TA varA, TB varB)
{
VarA = varA;
VarB = varB;
}
public void StartThread()
{
ThreadPool.QueueUserWorkItem(Worker, this);
}
public void Worker(object obj)
{
var state = obj as RunTask<TA,TB>;
Console.WriteLine(state.VarA + ", " + state.VarB);
}
}
修改:
如果您需要一个需要更新UI的解决方案,这可能是一个更好的解决方案
将参数放在一个像这样的单独的类中可能是一个更好的解决方案
在注释//更新列表
public class ListForm : Form
{
private static readonly object _listResultLock = new object();
private readonly Action<TaskResult> _listResultHandler;
public ListForm()
{
Load += ListForm_Load;
_listResultHandler = TaskResultHandler;
}
private void ListForm_Load(object sender, EventArgs e)
{
new RunTask(new Task("varA", "varB", TaskResultHandler)).StartThread();
}
public void TaskResultHandler(TaskResult result)
{
if (InvokeRequired)
{
Invoke(_listResultHandler, result);
return;
}
lock (_listResultLock)
{
// Update List
}
}
}
public class Task
{
public Action<TaskResult> Changed { get; private set; }
public string VarA { get; private set; }
public string VarB { get; private set; }
public Task(string varA, string varB, Action<TaskResult> changed)
{
VarA = varA;
VarB = varB;
Changed = changed;
}
}
public class TaskResult
{
public string VarA { get; private set; }
public string VarB { get; private set; }
public TaskResult(string varA, string varB)
{
VarA = varA;
VarB = varB;
}
}
public class RunTask
{
private readonly Task _task;
public RunTask(Task task)
{
_task = task;
}
public void StartThread()
{
ThreadPool.QueueUserWorkItem(Worker, _task);
}
public void Worker(object obj)
{
var state = obj as Task;
if (state == null) return;
if (state.Changed == null) return;
state.Changed(new TaskResult("this is " + state.VarA, "this is " + state.VarA));
}
}
答案 1 :(得分:3)
线程的start方法接受一个对象参数。
如果您的方法接受多个参数,那么您可以很好地将包含参数的类的对象传递给它。然后,您可以在方法中将其取消装箱。
Thread.Start(对象)
http://msdn.microsoft.com/en-us/library/system.threading.thread.start.aspx
<强>更新强>
在你的情况下,试试这个,
string varC = varA + "," + varB;
Thread.Start(varC);
并在您的方法中
string args[] = ((string)par).Split(',');
答案 2 :(得分:1)
如果你知道将为线程提供什么,那么你可能想要将对象传递给它。
在此处阅读更多内容 - &gt; http://msdn.microsoft.com/en-us/library/6x4c42hc.aspx
示例:
void someFunction()
{
Thread t = new Thread(doWork);
然后,
t.Start(new int[] { 1, 2 }); //two values passed to the thread.
或者,
t.Start(1); //one value passed to the thread.
}
现在,方法 -
void doWork(object data)
{
System.Collections.IList list = data as System.Collections.IList;
if (list != null)
{
object[] _objArr = data as object[];
foreach (object io in list)
{
System.Diagnostics.Trace.WriteLine(io);
}
}
else
{
System.Diagnostics.Trace.WriteLine(data);
}
}
答案 3 :(得分:0)
你可以用不同的方式在另一个线程中使用参数执行方法: 通过Thread类,通过System.ComponentModel.BackgroundWorker,通过ThreadPool。 如果经常调用方法,我认为ThreadPool适合:
ThreadPool.QueueUserWorkItem(
(args)=>
{
try
{
//args - object, you can put in it string[] or
// whatever you want
// do work
}
catch(Exception e)
{
// dont throw exceptions in this thread
// or application will crashed
}
}
);
您可以在msdn上阅读有关此类的内容:
http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx
http://msdn.microsoft.com/en-us/library/system.threading.parameterizedthreadstart.aspx
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
答案 4 :(得分:0)
您可以使用委托代替System.Thread
。
e.g:
public delegate void RunMyMethod(String a, String b);
RunMyMethod myDelegate = new RunMyMethod(MyMethod);
myDelegate.BeginInvoke(someAFromSomeWhere, someBFromSomeWhere);
MyMethod是您要运行的方法,并且必要时会从中提取参数。