gpt4 book ai didi

c# - 从不同的线程调用相同的方法

转载 作者:行者123 更新时间:2023-11-30 14:01:49 25 4
gpt4 key购买 nike

例如我们有 5 个正在运行的线程。他们每个人都调用相同的方法。当调用方法时,它会在当前线程上运行吗?这意味着相同的方法将在(相对)相同的时间分别在不同的线程上运行?

例子:

public string GetHhmlCode(string url)
{
// ... Some code here
return html;
}

如果我们同时从不同的线程以不同的参数调用这个方法,结果将返回到相应的线程,这意味着代码在不同的线程上分开运行?

最佳答案

第一个问题的简短回答是:是的!该方法将由多个线程同时执行。

第二个问题的答案是:是(有保留)!如果您从给定的线程上下文进入,那么该方法将返回到相同的线程上下文,并且所有线程通常会表现得好像其他线程不存在一样。然而,如果线程必须读取和/或写入同一个变量,这将很快改变。考虑这种情况:

class HttpClient
{
private volatile bool _httpClientConnected;
//.. initialize in constructor

public string GetHtmlCode(string url)
{
string html = string.Empty;
if(_httpClientConnected)
{
html = FetchPage(url);
}
return html;
}

public void Connect()
{
_httpClientConnected = true;
ConnectClient();
}

public void Disconnect()
{
_httpClientConnected = false;
DisconnectClient();
}
}

假设需要连接客户端才能成功获取页面,那么请考虑以下执行顺序:

Thread 1: calls GetHtmlCode
Thread 1: initialize local html variable
Thread 3: calls Disconnect()
Therad 2: calls GetHtmlCode
Thread 2: initialize local html variable
Thread 1: evaluate _httpClientConnected flag
Thread 3: sets _httpClientConnected to false
Therad 3: calls DisconnectClient() and successfully disconnects
THread 3: exits the Disconnect() method.
Thread 1: calls FetchPage()
Therad 2: evaluates _httpClientConnected flag
Thread 2: returns empty html string
Therad 1: catches an exception because it attempted to fetch a page when the client was disconnected

线程 2 正确退出,但线程 1 可能抛出异常,这可能会导致您的代码出现其他问题。请注意,读/写标志本身是安全的(即这些操作是原子的,并且由于标志被标记为 volatile 而对所有线程可见),但是存在竞争条件,因为标志可以在线程已经设置之后设置评估了它。在这种情况下,有几种方法可以防止出现此问题:

  1. 使用同步块(synchronized block)(类似于 lock(syncObject){...})
  2. 为每个线程创建一个单独的 http 客户端(可能更高效并且避免同步)。

现在让我们看另一个例子:

public string GetHtmlCode(string url)
{
string html = string.Empty;
string schema = GetSchema(url);
if(schema.Equals("http://"))
{
// get the html code
}
return html;
}

假设发生以下情况:

Thread 1: calls GetHtmlCode("http://www.abc.com/");
Thread 1: html is assigned an empty string
Thread 2: calls GetHtmlCode("ftp://www.xyz.com/");
Thread 2: html is assigned an empty string
Therad 1: assigns it's schema to the schema variable
Thread 2: assigns it's schema to the schema varaible
Thread 2: evaluates schema.Equals("http://")
Thread 1: evaluates schema.Equals("http://")
Thread 1: fetches html code
Therad 2: returns html
Therad 1: returns html

在这种情况下,两个线程都以不同的参数进入方法,只有线程 1 以允许它获取页面的参数进入,但线程 2 没有干扰线程 1。发生这种情况的原因是因为线程不要共享任何公共(public)变量。一个单独的 url 参数实例被传入,每个线程也得到它自己的本地模式实例(即模式不共享,因为它只存在于调用线程的上下文中)。

关于c# - 从不同的线程调用相同的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7536760/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com