为什么线程无限循环?

时间:2016-02-24 22:36:55

标签: c# multithreading

我使用的是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);
}

2 个答案:

答案 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