我想創建一個簡單的「鋼琴」應用程序,我可以在UI未被阻止時按下按鈕。調用線程必須是STA錯誤
private void Form1_Load(object sender, EventArgs e)
{
Thread t = new Thread(() => keyboard());
t.SetApartmentState(ApartmentState.STA);
t.Start();
}
public async void keyboard()
{
while(true)
{
if (Keyboard.IsKeyDown(Key.A))
{
btn_A_firstDo.BeginInvoke((Action)(() => btn_A_firstDo.Enabled = false));
//Play some music here...
await Task.Delay(1000);
btn_A_firstDo.BeginInvoke((Action)(() => btn_A_firstDo.Enabled = true));
}
}
}
我已經得到了我無法弄清楚它解決了一個錯誤:「調用線程必須爲STA,因爲許多UI組件都需要這種」 我在這部分代碼收到此錯誤:
if(Keyboard.IsKeyDown(Key.A))
我還沒有完全不顧我搜索了這個理解這個錯誤。 我的問題如下:
- 我該怎麼解決這個錯誤?這是什麼原因造成的?
- 我不認爲我正確使用了
await
。 我想要例如並行按下2個鍵而不會阻塞UI。 如何解決這個問題? - 有什麼方法可以讓我的代碼更優雅嗎?
編輯: 我已經想通了,工作代碼: (也訂閱事件KeyDown
工作,例如將顯示..)
public async void keyboard(Key key)
{
await Task.Run(() => {
this.BeginInvoke((Action) (() => {
btn_A_firstDo.Enabled = false;
// Play some music..
}));
Thread.Sleep(200);
this.BeginInvoke((Action) (() => {
btn_A_firstDo.Enabled = true;
}));
});
}
訂閱事件KeyDown
:
private void Piano_Load(object sender, EventArgs e)
{
this.KeyPreview = true;
this.KeyDown += SubKeyDown; // Deligate this event.
}
// Subscribing to event.
void SubKeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
switch(e.KeyCode)
{
case Keys.A:
keyboard(Key.A);
break;
// Continue with the cases...
default:
break;
}
}
可能是* 3 *的答案:您應該訂閱事件而不是運行循環來檢查是否按下了某個鍵。 –
或者如果在這種情況下沒有任何適當的事件,請使用「計時器」。 –
主要問題呢?我該如何解決它? –