使用两个参数启动线程

时间:2010-04-13 08:30:07

标签: c# multithreading parameters class-design

我有一个在一个事件上调用的方法,它给我提供了两个变量varA,varB(两个字符串)。这个方法经常被新信息调用,因此我创建了一个单独的方法来接受这两个参数。我想在一个线程中运行此方法,但是已经解决了Thread.Start不接受参数的问题。

我尝试了一些假设的方法,但到目前为止还没有运气..我认为最好的办法是创建一个单独的类,并在那里处理..但是我有一个List,我将数据插入

,当单独的类试图访问该列表时,它会死路一条。

有人可以帮助我吗?

5 个答案:

答案 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是您要运行的方法,并且必要时会从中提取参数。