【问题标题】:thread has not been started线程尚未启动
【发布时间】:2014-06-10 16:12:59
【问题描述】:

我正在开发一个基本的线程程序。我对 C# 和 WPF 比较陌生。我基本上要做的是在线程内运行一个方法,以便在该方法运行时获得输入。如果收到这样的输入,程序应该告诉线程完成它正在处理的当前对象并停止。

我的问题是,我无法得到线程已经启动的迹象。即使我尝试让线程像这样运行无限循环,

while(true);

仍然没有迹象表明线程正在运行,并且在尝试 thread.join 时出现 ThreadStateException。

我试过检查

thread.IsAlive

我试过了

thread.ThreadState == ThreadState.Running

我知道以上内容不正确,但我感到绝望。

这样构造线程

Thread t = new Thread(new ThreadStart(methodToRun));
t.Start();

我确信该方法正在运行,但是该线程没有表明它正在运行。

在我的研究中,我发现与此错误有关的是 ThreadStateException: Thread has not been started when trying to join a thread 也许我不明白,但问题似乎是他在加入之前中止并中止然后重新开始,我绝不会中止程序中的线程。

感谢大家的帮助,我将发布更多需要的信息或编辑此帖子以符合规范。我很抱歉,因为我是新人。

【问题讨论】:

  • 不要永远使用while(true);。此外,我们已经很多年没有使用过Thread 类了。相反,请使用 Task 类,如果您使用的是 .NET 4.5,甚至可以使用新的 asnycawait 关键字。
  • 找我的地方是methodToRun
  • 可能这不是最好的方法,但它可以工作,并且在 Linux 进程中以这种方式完成。当您启动线程时,将此数据写入文件。然后您阅读该文件并了解该线程正在运行。从线程末尾的文件中删除信息。您可以使用数据库和内存数据库(.Net 数据集)代替文件。
  • 为了表明线程曾经运行过,断点可能会起作用
  • 我使用 while(true); 的唯一原因是为了确保我在运行线程的方法中。 methodToRun 现在只包含用于调试的无限循环。这个程序是在 4.0 上创建的,我相信 Task 是 4.5 的新功能吗?

标签: c# wpf multithreading


【解决方案1】:

尝试使用Task class 而不是Thread 类,因为它更容易且更新。您可以像这样轻松地异步调用方法:

Task.Factory.StartNew(methodToRun);

此外,这些Task 对象可以使用CancellationToken(来自链接页面)轻松取消:

var tokenSource2 = new CancellationTokenSource();

CancellationToken ct = tokenSource2.Token;

var task = Task.Factory.StartNew(() =>
{

    // Were we already canceled?
    ct.ThrowIfCancellationRequested();

    bool moreToDo = true;
    while (moreToDo)
    {
        // Poll on this property if you have to do 
        // other cleanup before throwing. 
        if (ct.IsCancellationRequested)
        {
            // Clean up here, then...
            ct.ThrowIfCancellationRequested();
        }

    }
}, tokenSource2.Token); // Pass same token to StartNew.

tokenSource2.Cancel();

您可以从 MSDN 上的Task Cancellation 页面了解更多信息。

【讨论】:

  • 感谢您的回答。我将牢记Task类并学习它以便将来使用它。非常感谢。
  • 如果这个答案帮助你解决了你的问题,那么请accept it,按照本网站的惯例。
【解决方案2】:

您可以通过在启动线程时设置为true 的简单标志来做到这一点。如果您使用的是 .net 4.0 或更高版本,您还可以考虑使用支持取消的任务并行库。这是example

【讨论】:

  • 我尝试使用我自己的 bool 标志,但是当我尝试 t.Join() 时,我得到 ThreadStateException“线程尚未启动。”
  • 您必须等到标志设置为true。您是想立即join 还是通过用户驱动的操作(如按下按钮)?
  • 是的,按下按钮,在启动线程和尝试 Join() 之间有几秒钟的时间
  • 也许线程已经结束了?如果您这样做是出于学习目的,您可以尝试在工作函数中添加 Thread.Sleep(2000)。这可能允许您使用join。但通常你设置某种标志或取消标记来停止线程。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-06
  • 2020-04-28
  • 2016-05-13
  • 2010-10-14
  • 1970-01-01
  • 2019-04-30
  • 1970-01-01
相关资源
最近更新 更多