使用两个参数启动线程

发布于 2024-08-28 11:24:01 字数 261 浏览 6 评论 0原文

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

我已经尝试了一些假设的方法,但到目前为止还没有运气..我认为我最好的选择是创建一个单独的类,并在那里处理它..但是我有一个列表,我正在将数据插入其中,然后点击当单独的类尝试访问该列表时,这是一个死胡同,因为它位于不同的类中。

有人可以帮我吗?

I've got a method that gets called on an event, which presents me with two variables varA, varB (both strings). This method gets called with new information quite frequently, thus I have created a separate method that takes in the two parameters. I want to run this method in a thread, however have struck the issue that Thread.Start will not accept parameters.

I've tried a few supposed methods, but have so far had no luck.. I think my best bet is to create a separate class, and handle it there.. However I have a List which I am inserting data into, and hit a dead end when the separate class tried to access that list, since it was in a different class.

Can someone help me out here please?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

爱,才寂寞 2024-09-04 11:24:01

一个简单的解决方案...
这会将 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 的解决方案,这可能是一个更好的解决方案。
将参数放在像这样的单独的类中可能是更好的解决方案。
在注释后插入更新列表的代码 // Update List

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

A simple solution...
This will print varA, varB to the console.

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

Edit:
If you want a solution where you need to update the UI this is probably a better solution.
And it is probably a better solution to put the arguments in a separate class like this.
Insert code to update list after the comment // Update List

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));
    }
}
栀梦 2024-09-04 11:24:01

线程的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(',');

The start method of thread accepts an object parameter.

If your method accepts multiple parameters, then you can very well pass an object of your class containing the parameters into it. You can then unbox it in your method.

Thread.Start(Object)

http://msdn.microsoft.com/en-us/library/system.threading.thread.start.aspx

Update

In your case, try this,

string varC = varA + "," + varB;
Thread.Start(varC);

and in your method

string args[] = ((string)par).Split(',');
囚你心 2024-09-04 11:24:01

如果您知道将向线程提供什么,那么您可能需要向其传递对象。

在这里阅读更多内容 -> 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);
    }
}

If you know what will be supplied to the thread, then you may want to pass objects to it.

Read more here -> http://msdn.microsoft.com/en-us/library/6x4c42hc.aspx

Example:

void someFunction()
{
    Thread t = new Thread(doWork);

Then,

    t.Start(new int[] { 1, 2 }); //two values passed to the thread.

Or,

    t.Start(1); //one value passed to the thread.
}

Now, the method -

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);
    }
}
悲念泪 2024-09-04 11:24:01

您可以通过不同的方式在另一个线程中执行带参数的方法:
通过 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

you can execute method with parameters in another thread in different ways:
via Thread class, via System.ComponentModel.BackgroundWorker, via ThreadPool.
If method gets called frequently, i think ThreadPool ll fit:

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

You can read about this classes on 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

稳稳的幸福 2024-09-04 11:24:01

您可以使用委托,而不是使用 System.Thread。

例如:

public delegate void RunMyMethod(String a, String b);

RunMyMethod myDelegate = new RunMyMethod(MyMethod);
myDelegate.BeginInvoke(someAFromSomeWhere, someBFromSomeWhere);

其中 MyMethod 是您要运行的方法,并且从需要的地方提取参数。

Instead of using System.Thread, you could use a delegate.

e.g.:

public delegate void RunMyMethod(String a, String b);

RunMyMethod myDelegate = new RunMyMethod(MyMethod);
myDelegate.BeginInvoke(someAFromSomeWhere, someBFromSomeWhere);

Where MyMethod is the method you want to run, and the parameters are pulled from wherever necessary.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文