【问题标题】:Combining Thread with parameters and return value将Thread与参数和返回值结合起来
【发布时间】:2015-03-05 13:29:45
【问题描述】:

所以我最近一直在使用多线程,因为我是新手,所以我可能做一些基本错误..

Thread mainthread = new Thread(() => threadmain("string", "string", "string"));
mainthread.Start();

上面的代码完美无缺,但现在我想从我的线程中取回一个值。 为此,我在 SO 上搜索并找到了以下代码:

  object value = null; 
  var thread = new Thread(
    () =>
    {
      value = "Hello World"; 
    });
  thread.Start();
  thread.Join();
MessageBox.Show(value);
}

我不知道如何将两者结合起来。

返回值将是一个字符串。

感谢您对新手的帮助,我尝试将它们组合起来,但由于我缺乏经验而出错

编辑:

我的话题:

public void threadmain(string url,string search, string regexstring) {

    using (WebClient client = new WebClient()) // WebClient class inherits IDisposable
    {
        string allthreadusernames = "";
        string htmlCode = client.DownloadString(url);

        string[] htmlarray = htmlCode.Split(new string[] { "\n", "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
        foreach (string line in htmlarray)
        {
            if (line.Contains(search))
            {

                var regex = new Regex(regexstring);
                var matches = regex.Matches(line);
                foreach (var singleuser in matches.Cast<Match>().ToList())
                {
                    allthreadusernames = allthreadusernames + "\n" + singleuser.Groups[1].Value;


                }
            }
        }

        MessageBox.Show(allthreadusernames);

    }

}

【问题讨论】:

  • 签出异步/等待
  • 您不想从线程中获取值,而是想从函数中检索值。线程本身没有值。它们可用于处理工作。您想要返回的工作的结果。

标签: c# multithreading


【解决方案1】:

一个简单的解决方案是对异步操作使用另一个抽象级别:Tasks

例子:

public static int Calculate()
{
  // Simulate some work

  int sum = 0;
  for (int i = 0; i < 10000; i++)
  {
    sum += i;
  }
  return sum;
}

// ...

var task = System.Threading.Tasks.Task.Run(() => Calculate());
int result = task.Result; // waits/blocks until the task is finished

除了task.Result,您还可以使用await task(异步/等待模式)或task.Wait(+超时和/或取消令牌)等待任务。

【讨论】:

  • 效率一样吗?如果有,有什么区别?
  • @tim_po 更有效率。旋转线程只是错误的方式(但并非总是如此)。因此,在创建任务时,可以对线程进行一定的抽象(任务不需要在不同的线程上执行,而是由调度程序决定......)。参见例如blog.slaks.net/2013-10-11/threads-vs-tasksstackoverflow.com/a/13429164/57508
  • 区别基本上是任务从操作系统中抽象出创建线程的责任,让你专注于为它提供你想要它做的工作,这更有效的API和性能也是明智的(引入的通用,新的线程池实现......等)
  • 我觉得这个答案可以受益于与提问者如何使用任务完成类似的事情相关联。你和我都知道这会很简单,但不是每个人都会这样做。就目前而言,这是一个仅限链接的答案。
  • @MatthewHaugen 添加了一个示例
【解决方案2】:

线程实际上不应该表现得像函数。您发现的代码仍然缺乏读取/写入输出变量的同步/线程安全性。

Task Parallel Library 提供了更好的抽象,Tasks

你的问题可以通过类似下面的代码来解决:

var result = await Task.Run(() => MethodReturningAValue());

像这样运行任务实际上更轻量级,因为它只从 SynchronizationContext 或 .NET 线程池借用现有线程,开销较低。

我强烈推荐Stephen Cleary's blog series 使用任务来实现并行性和异步性。它应该会回答您所有进一步的问题。

【讨论】:

  • 我尝试使用线程并且它非常慢,使用线程我能够同时执行许多操作,但任务似乎在等待..
  • 在我的示例中,正在等待创建的任务。如果省略await 关键字(或Wait 方法/Result 属性),则可以同时启动多个Task,然后使用例如await Task.WhenAll 进行同步。
  • var taskresult = Task.Run(() => threadmain("string", "string", "string")); MessageBox.Show(taskresult); //不起作用,告诉我我不能把 变成字符串?
猜你喜欢
  • 2021-11-02
  • 1970-01-01
  • 1970-01-01
  • 2013-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-28
  • 2017-09-24
相关资源
最近更新 更多