c#如何在开始另一个线程之前检查一个线程

时间:2016-11-30 05:39:51

标签: c# multithreading visual-studio

这是我第一次尝试在应用程序中使用线程。 我知道之前已经问过这个问题,但是我看到的解决方案在我的情况下无法看到如何应用它们。

我有一个程序,每60秒在一个计时器上刷新一次datagridview。数据来自SQL数据库。此计时器还启动工作线程以查找特定的蓝牙设备,并根据其在后台的调查结果更新数据库。蓝牙查找速度特别慢,这就是我把它放在工作线程中的原因。

我的问题是,有时新工作线程在前一个工作线程完成之前就开始了。至少这是我得到的错误的唯一合理解释。当一个可以锁定文件的东西是来自同一个应用程序的另一个工作线程时,最重要的是文件锁定错误。

这是我用来启动后台线程的代码。

private void timerScreenRefresh_Tick(object sender, EventArgs e)
{
    if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");

    // If the user is not on a Remote desktop connection
    if (!remoteDesktopUser)
    {

        // Run the Bluetooth Search in a worker thread
        Thread thread = new Thread(new ThreadStart(this.checkProximity));
        thread.IsBackground = true;
        thread.Start();
    }

    // Load User Data from the DB and display on the screen
    loadUserData();
}

似乎解决方案是使用thread.IsAlive()但我找不到一个好的例子。当我刚刚使用“Thread thread = new Thread()”创建一个新线程时,尝试检查线程是否存在似乎很奇怪

显然我错过了一些东西。我正在使用Visual Studio 2008。 谢谢你的任何想法 大卫

更新

基于krw12572下面提出的解决方案,我尝试了这个......

我将!=更改为==因为我仍然希望每次都在主线程中运行loadUserData()方法。

在编辑器中,我在“_bluetoothSearchThread”上得到一个绿色下划线,告诉我该字段从未被分配,并且将始终具有NULL值。

在运行时,我在此行上收到“对象引用未设置为对象的实例”错误。

if (_bluetoothSearchThread == null && _bluetoothSearchThread.IsAlive)

如何分配此值?

    private Thread _bluetoothSearchThread;
    private void timerScreenRefresh_Tick(object sender, EventArgs e)
    {
        if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");

        // Check if Worker Thread is already running.
        if (_bluetoothSearchThread == null && _bluetoothSearchThread.IsAlive)
        {
            if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "Previous Worker Thread not running");

            // If the user is not on a Remote desktop connection
            if (!remoteDesktopUser)
            {
                // Check if the users mobile phone is within range
                // Run the Bluetooth Search in a worker thread

                Thread thread = new Thread(new ThreadStart(this.checkProximity));
                thread.IsBackground = true;
                thread.Start();
            }
        }
        else 
        {
            if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "Worker Thread still running don't start another one");
        }

        // Load User Data from the DB and display on the screen
        loadUserData();
    }

更新2

好吧,我想我已经弄明白了。 我将!= Null改回原来的状态,并将IF和Else转向另一个方向。

然后我不得不使用我的大脑并将“线程”更改为“_bluetoothSearchThread”

现在代码编译并运行。现在我只需要通过触发导致文件锁定错误的条件来测试它,看看我是否确实修复了原始问题。如果它有效,我会将krw12572答案标记为正确。

更新2.5 我也不得不移动这一行,因此它不会太快创建新实例

_bluetoothSearchThread = new Thread(new ThreadStart(this.checkProximity));

所以这是可行的解决方案。

    private Thread _bluetoothSearchThread;
    private void timerScreenRefresh_Tick(object sender, EventArgs e)
    {
        if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");


        // Check if Worker Thread is already running.
        if (_bluetoothSearchThread != null && _bluetoothSearchThread.IsAlive)
        {
            // Thread is still running.  Just log it and move on.
            if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "******** Worker Thread still running don't start another one *********");
        }
        else 
        {
            if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "Previous Worker Thread not running");

            // If the user is not on a Remote desktop connection
            if (!remoteDesktopUser)
            {
                // Check if the users mobile phone is within range
                // Run the Bluetooth Search in a worker thread
                _bluetoothSearchThread = new Thread(new ThreadStart(this.checkProximity));
                _bluetoothSearchThread.IsBackground = true;
                _bluetoothSearchThread.Start();
            }
        }

        // Load User Data from the DB and display on the screen
        loadUserData();
    }

3 个答案:

答案 0 :(得分:4)

修改

经过研究,在你的情况下使用# /etc/nginx/sites-available/default server { listen 80; listen [::]:80; server_name example.com www.example.com; # <-- CHANGED THIS LINE return 301 https://example.com$request_uri; } server { listen 443 ssl http2 default_server; listen [::]:443 default_server ipv6only=on; include snippets/ssl-params.conf; # ssl config info server_name example.com; # ... the rest of the site config ... } 并不是一种安全的方法。

您应该使用Thread.IsAlive

<强>文档

  

阻止调用线程,直到由此表示的线程   实例终止或指定的时间过去,同时继续   执行标准COM和SendMessage抽取。

示例:

Threa.Join()

答案 1 :(得分:4)

如果您一次只想运行一个线程,则可以创建一个存储Thread实例的字段。使用该线程实例,您可以使用_threadInstance.IsAlive检查它是否已在运行。

private Thread _bluetoothSearchThread;
private void timerScreenRefresh_Tick(object sender, EventArgs e)
{
    if(_bluetoothSearchThread != null && _bluetoothSearchThread.IsAlive) 
        return;        //It means one thread is already performing the search operation.

    if (LocalUtilities.Debug > 3) LocalUtilities.writeLogFile(4, "Primary", LocalUtilities.getCurrentMethod() + "()", "");

    // If the user is not on a Remote desktop connection
    if (!remoteDesktopUser)
    {

        // Run the Bluetooth Search in a worker thread
        _bluetoothSearchThread = new Thread(new ThreadStart(this.checkProximity));
        _bluetoothSearchThread.IsBackground = true;
        _bluetoothSearchThread.Start();
    }

    // Load User Data from the DB and display on the screen
    loadUserData();
}

答案 2 :(得分:0)

您可能希望使用Task代替Thread

// Create dummy task
Task task = Task.Run(() => { });

private void timerScreenRefresh_Tick(object sender, EventArgs e)
{
    ...
    // add continuation to current task
    task.ContinueWith(t => checkProximity);
    ...
}

新任务将仅在前一个任务之后执行。

但是,如果任务在Tick期间没有时间运行,它们将累积在队列中。