我使用的是VS2010 .Net 4.0,因此我无法使用await
来电。我有一个线程下载的东西,我不应该继续状态变为“完成”。所以我使用while循环阻塞线程。但不知何故,它变成了无限循环。我是否正确创建了线程?
string status = string.Empty;
Thread thread = new System.Threading.Thread(() =>
{
status = Download(downloadKit, patchTitle);
});
thread.Start();
thread.Join();
// Loops here forever
while (status != "Done")
{
//Thread.Sleep(25); // Tried this as well, same result
Thread.SpinWait(1);
}
答案 0 :(得分:0)
线程有时会导致一些奇怪的东西,你需要告诉编译器你正在预先形成不安全的东西,你可以通过做var nstatus = Volatile.Read( ref status )
然后与之进行比较来做到这一点。
string nstatus = status;
// Loops here forever
while (nstatus != "Done")
{
//Thread.Sleep(25); // Tried this as well, same result
Thread.SpinWait(1);
nstatus = Volatile.Read(ref status);
}
其他替代方法是使用Thread.MemoryBarrier()
调用(我认为这是在Volatile调用中完成的),这会阻止编译器重新排序语句:
// Loops here forever
while (status != "Done")
{
//Thread.Sleep(25); // Tried this as well, same result
Thread.SpinWait(1);
Thread.MemoryBarrier();
}
要看的好资源是http://www.albahari.com/threading/part4.aspx,深入研究.NET 4.0中的线程
答案 1 :(得分:0)
您需要了解调用线程中的thread.Join();
块,直到加入的线程终止。一旦你理解了这一点,你就会发现在调用线程中对状态值进行while循环是很愚蠢的,好像你已经通过了连接那么状态的值永远不会再改变,除非你添加了这样做的代码。
string status = string.Empty;
Thread thread = new System.Threading.Thread(() =>
{
status = Download(downloadKit, patchTitle);
});
thread.Start();
thread.Join();
//no point in looping here, if the thread finished, it has already assigned the
//value it is going to assign to the status variable
if (status == "Done")
{
//do what needs to be done
}
else
{
//uh oh, handle the failure here
}
为了满足在status=="Done"
之前无法继续的要求,您可以将while循环放在子线程中,以便它继续尝试下载函数,直到它返回&#34;完成&#34;:< / p>
string status = string.Empty;
Thread thread = new System.Threading.Thread(() =>
{
while(status != "Done")
status = Download(downloadKit, patchTitle);
});
thread.Start();
thread.Join();
//do what needs to be done