[英]thread races and the lock keyword
我的應用程序具有一個登錄區域,該登錄區域使用線程訪問數據庫而不凍結UI。
在登錄期間,系統進行一些操作以打開主窗口,並在另一個線程中加載用戶數據(和權限)。
但是有時,當數據庫掛起時,系統會在加載用戶之前完成加載。
系統執行的最后一個操作是應用權限(將線程與用戶數據一起加載)。
我還有一個靜態的User
對象,該對象保存進行登錄的用戶的數據,例如其權限等。
當應用程序在加載用戶之前從靜態用戶對象獲取數據時,就會出現問題。 權限為空,未正確應用,從而導致不良行為。
如何確保靜態用戶已加載,並且僅在極端的網絡/數據庫延遲情況下凍結UI?
我嘗試使用lock
,但是它根本不起作用。
這是我的代碼:
int id = User.GetId(user, password); // returns 0 if the user does not exists
if (id != 0)
{
new Thread(() =>
{
lock (User.CurrentUser) // Try to lock the static CurrentUser object
{
User.LoadCurrentUser(id); // Loads the CurrentUser object
}
}).Start();
InitializeSystem(); //Make some work on the system. After that, this
//will get the User.CurrentUser object to apply the
//user's permissions.
}
方法User.LoadCurrentUser(id);
填補用戶。
我知道鎖不起作用,因為我放了Thread.Sleep(5000);
進入鎖,系統將在2秒內以錯誤的權限啟動。
不考慮刪除線程,因為它會破壞我的UI。
編輯
我需要使用.Net Framework 4.0來確保Windows XP兼容性。
這是await
或鏈接任務的理想人選。
等待版本:
async void YourLoginButtonEventHandler() {
int id = User.GetId(user, password); // returns 0 if the user does not exists
if (id != 0) {
await Task.Run(() => User.LoadCurrentUser(id)); // Loads the CurrentUser object
InitializeSystem();
}
}
或者,您可以將它們鏈接起來:
if (id != 0) {
Task.Run(() => User.LoadCurrentUser(id))
.ContinueWith(t => InitializeSystem(), TaskScheduler.FromCurrentSynchronizationContext);
}
注意:可能是幾個語法錯誤。我直接在這里輸入。
我基本上想向您展示的是..您正在艱難地解決這個問題。 對於這種事情有更新的構造..學習它們:)
您可以使用Thread.Join阻塞主線程,直到另一個線程完成或超時。
int id = User.GetId(user, password); // returns 0 if the user does not exists
if (id != 0)
{
var newThread = new Thread(() =>
{
lock (User.CurrentUser) // Try to lock the static CurrentUser object
{
User.LoadCurrentUser(id); // Loads the CurrentUser object
}
}).Start();
InitializeSystem();
if (newThread.Join(someTimeOut))
// use the User.CurrentUser object to apply the user's permissions.
else
// thread timed out, waiting for user load takes too long...
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.