【发布时间】:2016-11-30 05:39:50
【问题描述】:
这是我第一次尝试在应用程序中使用线程。 我知道以前有人问过这个问题,但在我看过的解决方案中,我看不出如何在我的情况下应用它们。
我有一个程序,其中每 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 Around 反过来。
然后我不得不稍微动动脑筋,将“线程”更改为“_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();
}
【问题讨论】:
-
@BALA 我之前确实看到过该解决方案。它似乎过于复杂,我并没有真正理解它。明天我会尝试盲从它,看看是否有可行的东西出来。
-
@AshwinGupta 我已经阅读了那篇文章,它提出了一些不同的选项,但没有解释如何实际使用它们。至少不是我能理解的。
标签: c# multithreading visual-studio