在c#

时间:2015-07-02 14:56:16

标签: c# multithreading webclient

我在某处读到使用Thread.Abort()方法是杀死线程的最糟糕的方法之一,因为它没有释放分配给该线程的内存。 (我不知道这是不是真的,如果它是错误的,请纠正我。Abort()方法是我应该使用的方法。)因此,调用查杀线程的最佳方法是创建一个变量,如果线程可以运行则会对,即:

bool threadResult;
t = new System.Threading.Thread(() => doSomeStuff());
t.Start();
abortThread();
//***************************************************
bool threadCanRun = true;
void doSomeStuff()
{
   while(threadCanRun)
      // do work
}
void abortThread()
{
   threadCanRun = false;
}

但是......如果线程无法像这样停止怎么办?即:

void doSomeStuff()
{
   WebClient wc = new Webclient();
   string url = "www.mywebsite.com";
   string content = wc.DownloadString(url);
}

假设我想在这个线程上花费不到100毫秒^。如果它不会结束,直到时间过去(我使用以下结构:if (t.Join(100)))我应该以某种方式中止它以保持我的程序运行。那么,结束工作线程的正确方法是什么?

当然,在这种特殊情况下,我可以使用try-catch来处理大多数异常,但这只是一个例子。此外,如果我的连接非常慢并且网页非常大,则需要100毫秒以上,并且不会抛出任何异常。

PS。我几乎可以肯定它并不重要,但我正在使用一些Forms引用的WPF应用程序。目标FW是NET 4.0。

2 个答案:

答案 0 :(得分:0)

如果您希望线程能够在100ms内结束,则应设计线程以至少每100ms检查一次运行条件(threadCanRun)。你的问题太笼统,所以我不能给你更准确的答案。

此外,在threadCanRun = false;之后立即加入您的主题是一个很好的编程习惯,尽管有人可能不同意这一点。

答案 1 :(得分:0)

在我看来,使用 BackgroundWorker 类更安全但是如果你想使用 线程 那么你必须实现标志取消模式。 如果您使用的是.Net Framework 4.0,则可以使用 CancellationTokenSource 类,如下所示:

public partial class Form1 : Form
{
    CancellationTokenSource cancelSource = new CancellationTokenSource();
    int threadCounter = 0;
    int mainCounter = 0;

    public void doSomeStuff(CancellationToken cancelToken)
    {
        cancelToken.ThrowIfCancellationRequested();

        for (int i = 0; i < 100; i++)
        {
            threadCounter = i;
            // If you want to cancel the thread just call the Cancel method of the cancelSource.
            if (i == 88)
            {
                cancelSource.Cancel();
            } 

            if (cancelSource.IsCancellationRequested)
            {
                // Do some Thread clean up here
            }
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {

        new Thread(() => doSomeStuff(cancelSource.Token)).Start();

        // Do something else while the thread has not been cancelled
        while (!cancelSource.IsCancellationRequested)
        {
            mainCounter++;
        }

        textBox1.Text = "The thread was cancelled when 'mainCounter' was at: " + mainCounter.ToString();            
    }
}

您还可以使用 CancellationToken ,其中包含 IsCancellationRequested 属性和 ThrowIfCancellationRequested 方法。