use*_*041 3 .net c# multithreading thread-safety
基本上,我需要忙等到网页上出现一些html.我已经创建了以下代码来忙着等我:
public void ExecuteBusyWaitThreads()
{
foreach (Canidate canidate in allCanidates)
{
Thread newThread = new Thread(delegate()
{
BusyWait(canidate);
});
newThread.Start();
}
}
public bool BusyWait(Canidate canidate)
{
//hit that url, and wait for the claim all button to appear
string page = null;
while (found == false)
{
HttpWebRequest request = Canidate.GetHTTPRequest(canidate.URL);
//make sure we add the authentication cookes to the request
request = Canidate.AddCookiesToRequest(request, canidate.GetCookies());
page = new Canidate().GetPage(request);
if (page.ToLower().Contains("claim all"))
{
found = true;
NotifyAllThreads();
}
}
return true;
}
Run Code Online (Sandbox Code Playgroud)
所以,如果我有8 canidates,它将产生8个线程,每个线程都希望claim all出现在网页上.found是一个全局变量.一旦其中一个线程找到claim all,他们都应该保释.
关于这种方法,我有几个问题.首先,这是一个很好的方法.其次,每个线程都会获得忙等待功能的"副本".我的意思是,一个线程可以抢占另一个线程并更改该函数中的数据,或者它们每个都获得函数内声明的变量的副本.请注意,这两个函数都在同一个对象中.
在我回答你的问题之前,我必须指出你已经做出了关闭循环变量的恶劣行为.
首先,这是一个很好的方法.
不,不是真的.任意创建线程通常不是一个好主意.最好使用线程池技术.这是可以做到的ThreadPool.QueueUserWorkItem或Task类.
其次,每个线程都会获得忙等待功能的"副本".我的意思是,一个线程可以抢占另一个线程并更改该函数中的数据,或者它们每个都获得函数内声明的变量的副本.
每个运行的实例都BusyWait将获得自己的所有局部变量的副本(即.page和request).由于found在非本地范围内声明(可能是无论如何),因此它将在所有正在运行的实例之间共享BusyWait.因此,您当前的读取和写入found不是线程安全的,因为没有适当的同步机制.