2016-03-10 55 views
1

我想顯示窗口,但出現錯誤「調用線程必須是STA,因爲很多UI組件都需要這個」。我發現了這種溶劑,但每次寫這個都很困難。WPF與STA線程錯誤的靈活性

Application.Current.Dispatcher.Invoke((Action) delegate 
{ 
    msgBox = 
     new CustomMessageBox(
      "Файл добавлен в базу, строки " + errors + 
      " не были добавлены по причине неверных входных данных", 
      "Уведомление"); 
    msgBox.Show(); 
}); 

是否還有其他解決方案?我把CustomMessageBoxBelow

public partial class CustomMessageBox : Window 
{ 
    public CustomMessageBox() 
    { 
     InitializeComponent(); 
    } 

    public CustomMessageBox(string text, string title) 
    { 
     InitializeComponent(); 
     Title = title; 
     TextBlock.Text = text; 
    } 

    private void OkBtn_OnClick(object sender, RoutedEventArgs e) 
    { 
     this.Close(); 
    } 
} 
+0

顯示消息框在輔助線程是很少是個好主意,這被認爲是可怕的。如果它不是很糟糕,那麼幾乎每個人都會錯誤的。改爲使用BackgroundWorker或TaskScheduler.FromCurrentSynchronizationContext()。 –

+0

你在主要方法中有'STAThread'屬性嗎? – Valentin

回答

1

的代碼作爲WPF應用程序是STA應用,所有這些都與UI控件交易必須在UI線程的上下文中運行的邏輯。這正是Dispatcher用於 - 將該方法調用到UI同步上下文中。

我同意你提供的代碼不好,所以你必須重構它。我建議您創建一個將在後臺運行的方法,返回操作的狀態,其中可能包含錯誤代碼和警告。

的代碼可能是這樣的:

async void btnSave_Click(object sender, EventArgs e) 
{ 
    // get string result of the operation 
    var result = await Task.Run(() => SaveTheData()); 
    if (result != "OK") 
    { 
     msgBox = new CustomMessageBox(
        "Файл добавлен в базу, строки " + result + 
        " не были добавлены по причине неверных входных данных", 
        "Уведомление"); 
     msgBox.Show(); 
    } 
} 

我想說的另一件事是,你應該它被保存到數據庫之前檢查用戶輸入,這可以節省他們的時間。

0

創建一個輔助函數和異步調用的消息框在UI線程:

static void ThreadSafeMessageBox(String text) 
{ 
    Application.Current.Dispatcher.BeginInvoke(new Action(() => MessageBox.Show(text))); 
} 

void Test() 
{ 
    Task.Run(() => { ThreadSafeMessageBox("Hi!");}); 
}