【问题标题】:Store a thread with multiple parameters - WPF存储具有多个参数的线程 - WPF
【发布时间】:2015-06-30 04:51:37
【问题描述】:

我使用下面的代码来运行具有多个参数的线程:

public Thread StartTheThread(System.Windows.Threading.Dispatcher dispatcher, int param1, string param2)
{
    Thread t = new Thread(() => Work(Maingrid.Dispatcher, param1, param2));
    t.Start();
    return t;
}

public delegate void delegate1(Color randomparam, Color secondparam);

public void Work(System.Windows.Threading.Dispatcher dispatcher, int param1, string param2)
{
    dispatcher.Invoke(new delegate1(update), {Color.FromRgb(255, 255, 0),Color.FromRgb(170, 255, 170)});
}

public void update(Color randomparam, Color secondparam)
{
    ...
}

创建一个新线程通常需要“ThreadStart”或“ParameterizedThreadStart”方法。 Threadstart 方法适用于没有参数的线程,parameterizedthreadstart 方法适用于只有 1 个参数(作为对象)的线程。但我有不同类型的参数。由于这些方法是委托,我尝试使用自定义委托来存储线程以便稍后调用:

public delegate void starterdelegate(System.Windows.Threading.Dispatcher dispatcher, int param1, string param2);

public Thread StartTheThread(int param1, string param2)
{
    Thread t = new Thread(new starterdelegate(RealStart));
    ...
    return t;
}

但是在这种情况下,编译器会返回这个错误:

“重载解析失败,因为无法使用这些参数调用可访问的‘New’: “Public Sub New(start As System.Threading.ParameterizedThreadStart)”:“ThreadTraining.MainWindow.starterdelegate”类型的值无法转换为“System.Threading.ParameterizedThreadStart”。 'Public Sub New(start As System.Threading.ThreadStart)': 'ThreadTraining.MainWindow.starterdelegate' 类型的值无法转换为 'System.Threading.ThreadStart'。"

我的意思是多参数运行线程没有问题,但是当我想存储线程t时,我不想提交参数,因为它们会在我下次运行时更改线。如果我使用 ParameterizedThreadStart 方法并且不提交参数,编译器会抛出签名错误。如果我不使用所需的方法之一,编译器将抛出重载解析失败错误。

我什至不知道这是为什么:

Thread t = new Thread(() => Work(Maingrid.Dispatcher, param1, param2));

首先工作。这里的“new Thread”的参数如何与所需的方法兼容?我在这个页面上找到了这行代码:https://stackoverflow.com/a/1195915/2770195

有什么建议吗?

【问题讨论】:

  • 删除所有内容并使用async/await。此外,无论您在做什么,都应该使用 DataBinding。
  • 我真的不明白你想要达到什么目的。
  • @HighCore 你是什么意思?我不明白。
  • @OndrejJanacek 我只是不想提交参数来存储它们。为什么我需要?它只会消耗更多的冗余内存空间(因为我确信它的参数会在我下次运行它们之前发生变化)。出于这个原因,我觉得我做错了。一定有更好的办法

标签: c# wpf multithreading parameters


【解决方案1】:

您可以将参数封装在一个类中,但您也可以将您的逻辑封装在类中:

public class FooProcessor
{
    private readonly Color _color1;
    private readonly Color _color2;

    public FooProcessor(Color color1, Color color2)
    {
        _color1 = color1;
        _color2 = color2;
    }

    public Task ProcessAsync()
    {
        return Task.Run((Action) Process);
    }

    private void Process()
    {
        //add your logic here
    }
}

OT:如果您没有特定理由使用 Thread 而不是 Task,请使用 Task。一些较旧的教程使用线程,因为当时不存在任务。

【讨论】:

  • 这似乎可行,谢谢。所以每次我都会用新参数覆盖FooProcessor并调用ProcessAsync()。但我有一个问题。我有大量进程(线程、任务,无论它是什么),它们有可能同时运行,并且所有进程都必须能够单独控制(暂停、覆盖、中止等),并且它们的参数会随着时间而变化。 (下一条评论):
  • 您认为这是存储它们的最佳方式吗?我的意思是,在内部创建一个包含进程逻辑的参数类和创建一个从主线程引用进程逻辑的参数类在速度和内存消耗方面是否有所不同?我所有的线程都有相同的逻辑。 (注意:我的评论分为两部分,因为 stackoverflow 不允许我输入那么长的内容)
  • 对于每个进程,您必须创建 FooProcessor 的新实例。这很重要。如果您有大量进程,则不应使用线程,而应使用任务。你也可以使用Parallel.Foreachmsdn.microsoft.com/en-us/library/dd460720(v=vs.110).aspx
  • 我的意思是,在类中包含流程逻辑会影响性能吗?我的代码很长,我想知道程序是否会为每个 FooProcessor 单独存储 Process() void
【解决方案2】:

使用 ParameterizedThreadStart 委托。参考这里:

https://msdn.microsoft.com/en-us/library/system.threading.parameterizedthreadstart(v=vs.110).aspx

我认为你应该创建一个新类来封装你的参数,并将新的类实例作为参数发送到线程。

希望对您有所帮助。

【讨论】:

  • 这似乎简化了参数,谢谢。但是我仍然不明白为什么我不能只存储具有多个参数的线程,因为我实际上可以运行具有多个参数的线程。不过,这也是一个很好的解决方案。
  • 据我所知,目前不能将很多(超过 1 个参数)传递给线程。此外,将参数包装到对象中是一种最佳做法。想想如果你有 15 个参数需要传递给一个函数,你必须仔细盯着它们以纠正它们的位置......
  • 我曾经将我的参数包装到一个数组中,但是,就像你说的那样;当我有 15 个参数时,很难记住它们在数组中的位置。创建类似乎更方便。
  • 我将创建一个自定义的“Params”,其中包含 Param1、Param2、...等自动属性。在 Thread 的处理方法中,我会将对象转换为“Params”。因此,仅建议最佳实践。所以跟随与否取决于你。 :)
  • 好的,谢谢 :) 我希望我可以将您的回答标记为有用,但我还没有足够的声望点来做到这一点。我会尽可能将其标记为有帮助。
【解决方案3】:

在 SO 上有一个关于将多个参数传递给 ThreadStart 方法的问题的答案。我喜欢这个:

    static void Main(string[] args)
    {
        for (int i = 1; i < 24; i++)
        {
            Thread t = new Thread( ()=>ThreadWorkingStuff(i,"2"+i.ToString() ));
            t.Start();
        }
        Console.ReadKey();
    }

    static void ThreadWorkingStuff(int a, string b)
    {
        Console.WriteLine(string.Format("Thread{2}|  a={0} b={1}", a, b, Thread.CurrentThread.ManagedThreadId));
    }

【讨论】:

    猜你喜欢
    • 2023-03-31
    • 1970-01-01
    • 2021-11-24
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    相关资源
    最近更新 更多