【问题标题】:Run method in new Thread with parameters在带有参数的新线程中运行方法
【发布时间】:2018-08-15 21:10:33
【问题描述】:

我有 asp.net 核心控制器,它从 View 获取数据并使用它进行搜索

这是控制器代码

 private readonly GettingWords _repository;

    public HomeController(GettingWords repository){
        _repository = repository;
    }

    [HttpPost]
    public JsonResult SearchWord([FromBody] RequestModel model){
        var result = _repository.GettingWord(model.word, model.adress);
        return Json(result);
    }

这是它调用的方法

public class GettingWords
{
    public string  GettingWord(string word, string adress)
    {
        string result;
        HttpWebRequest request = (HttpWebRequest)WebRequest.Create(adress);
        HttpWebResponse response = (HttpWebResponse)request.GetResponse();
        Stream receiveStream = response.GetResponseStream();
        StreamReader readStream = null;

        if (response.CharacterSet == null)
        {
            readStream = new StreamReader(receiveStream);
        }
        else
        {
            readStream = new StreamReader(receiveStream, Encoding.GetEncoding(response.CharacterSet));
        }

        string data = readStream.ReadToEnd();
        string pattern = word;

        // Instantiate the regular expression object.
        Regex r = new Regex(pattern, RegexOptions.IgnoreCase);

        // Match the regular expression pattern against your html data.
        Match m = r.Match(data);

        if (m.Success)
        {
            result = "Word  " + word + "  finded in  " + adress;
        }
        else
        {
            result = "Word not finded";
        }
        response.Close();
        readStream.Close();
        return result;

    }
}

我需要使用这两个参数在新线程中运行 GettingWord。我怎样才能正确地做到这一点?

更新

我还需要设置最大线程数,所以我认为 Task<> 不适合这个

【问题讨论】:

  • 你应该使用HttpClient类和GetAsyncGettingWord应该声明为public async Task<string> GetWordAsync(string word, string adress)
  • 好的。但我也需要声明最大线程数,所以异步任务可能不适合这个? @CamiloTerevinto
  • 不,您根本不需要设置最大线程数。你认为你需要另一个线程,你不需要。使用适当的异步模式,而不是尝试强制使用线程模型
  • 你认为你会赢得什么?仅仅为了创建线程而创建线程不会让您的应用程序更快
  • 为什么需要在新线程中运行它?在等待“新线程”完成时,原始线程会做什么?正如@CamiloTerevinto 指出的那样,您应该异步并等待。任务非常适合这种情况。因为等待网络请求不需要线程。任务将允许线程在其他地方使用,直到 Web 请求返回。使用适当的异步模式将意味着您创建 0 个额外线程,因此无需担心最大线程数

标签: c# asp.net-core


【解决方案1】:

你的 Getting Words 类应该是这样的

public class GettingWords
{
    private static HttpClient _client = new HttpClient();

    public async Task<string>  GettingWordAsync(string word, string adress)
    {
        string result;
        string data = await _client.GetStringAsync(adress);
        string pattern = word;

        // Instantiate the regular expression object.
        Regex r = new Regex(pattern, RegexOptions.IgnoreCase);

        // Match the regular expression pattern against your html data.
        Match m = r.Match(data);

        if (m.Success)
        {
            result = "Word  " + word + "  finded in  " + adress;
        }
        else
        {
            result = "Word not finded";
        }
        return result;

    }
}

并像这样使用

私有只读 GettingWords _repository;

public HomeController(GettingWords repository){
    _repository = repository;
}

[HttpPost]
public async Task<JsonResult> SearchWord([FromBody] RequestModel model){
    var result = await _repository.GettingWordAsync(model.word, model.adress);
    return Json(result);
}

【讨论】:

  • 我在这个字符串有 400 个错误请求 string data = await _client.GetStringAsync(adress);
  • 这意味着您在 adress 变量中的地址在某种程度上不正确使用调试器或编写控制台来获取该变量中的值并尝试通过 Web 浏览器访问并查看它是否有效
  • 它适用于谷歌浏览器。我使用 HttpWebRequest 重写代码
【解决方案2】:

我能够通过这段代码解决异步问题

  public async Task<string> GettingWordAsync(string word, string adress)
    {
        HttpWebRequest req = WebRequest.CreateHttp(adress);
        req.Method = "GET";
        req.KeepAlive = true;   
        string result;
        string content = null;
        string pattern = word;
        HttpStatusCode code = HttpStatusCode.OK;
        try
        {
            using (HttpWebResponse response = (HttpWebResponse)await req.GetResponseAsync())
            {

                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                    content = await sr.ReadToEndAsync();

            }
        }
        catch (WebException ex)
        {

            using (HttpWebResponse response = (HttpWebResponse)ex.Response)
            {
                using (StreamReader sr = new StreamReader(response.GetResponseStream()))
                    content = sr.ReadToEnd();

                code = response.StatusCode;
            }

        }

                // Instantiate the regular expression object.
        Regex r = new Regex(pattern, RegexOptions.IgnoreCase);

        // Match the regular expression pattern against your html data.
        Match m = r.Match(content);

        if (m.Success)
        {
            result = "Word  " + word + "  finded in  " + adress;
        }
        else
        {
            result = "Word not finded";
        }
        return result;
    }
}

【讨论】:

  • 如果这对你有用,尤金你可以将自己的答案标记为正确答案,让未来的访问者更容易看到有效的方法
  • 不知道有等待时间。你必须给自己设置一个闹钟;)
【解决方案3】:

@Eugene 之前关于异步任务的评论是有效的。 如果您需要对任务计数进行更多控制,您可以在线程池中设置最大数量,或者无论如何更改默认的 TaskScheduler(例如,可以在 here 找到详细信息)。 这是我不建议做的事情。有人真正需要它是非常重要的。看起来你的情况可能是不正确/不清楚的业务任务。 如果您确定确实需要为该服务全局设置最大线程数,请考虑使用 TPL Dataflow 构建异步管道

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-18
    相关资源
    最近更新 更多