我正在嘗試鏈接任務,所以一旦完成下一個任務,但 UI 不會更新。我做了一門反應課程,其中一課是根據應用程式中的狀態更改更新 UI,這就是我想要復制的內容。更改應用程式的狀態(基本上我將運行運行回傳 bool 進行驗證的方法),然后相應地更新 UI,我也在使用系結,但由于某種原因它沒有按預期運行,我不不知道我是否錯誤地遵循了檔案。我可以更改或修復什么以使其作業,并且在一種async Task<T>方法中使用多個任務實際上是否正確
public async Task<string> Connect_To_Ip()
{
await Task.Run(() =>
{
details.State = "Connection To IP 127.0.01.258.....";
Task.Delay(5000).Wait();
}).ContinueWith(result => new Task(async () =>
{
await Task.Run(() =>
{
if (result.Status == TaskStatus.RanToCompletion)
{
details.State = "Validating Card Number......";
}
});
}), TaskContinuationOptions.OnlyOnRanToCompletion);
return details.State;
}
我如何呼叫原始任務
Task connect = Connect_To_Ip();
await connect;
uj5u.com熱心網友回復:
當你使用await然后你不需要Task.ContinueWith. 等待操作之后的一切都是延續。由于要在后臺執行緒上進行驗證,因此必須將更改發布回 UI 執行緒以更新 UI 元素,否則將產生跨執行緒例外。
這是因為 UI 元素不能從后臺執行緒更新,除非更新是通過INotifyPropertyChanged資料系結發生的。
執行此操作的一種方法是使用Dispatcher來呼叫 UI 執行緒上的 UI 操作或使用Progress<T>該類,該類將始終在 UI 執行緒上執行注冊的回呼。
您的固定和簡化代碼可能如下例所示:
public async Task ValidateAsync()
{
// Register the callback that updates the UI with the 'progressReporter'.
// Progress<T> must be instantiated on the UI thread it is associated with
var progressReporter = new Progress<string>(message => details.State = message);
// Execute the operation on a background thread
await Task.Run(() => ConnectToIp(progressReporter));
// Continuation starts here, after await
}
public async Task ConnectToIp(IProgress<string> progressReporter)
{
progressReporter.Report("Connection To IP 127.0.01.258.....");
await Task.Delay(TimeSpan.FromSeconds(5));
// Continuation starts here, after await
progressReporter.Report("Validating Card Number......");
}
建議盡可能使用異步 API,而不是使用后臺執行緒。例如,要在不阻塞 UI 的情況下連接到服務器,您可以使用
HttpClient client = new HttpClient();
HttpResponseMessage response = await client.GetAsync("http://www.contoso.com/");
許多 IO 類提供異步 API。
此外,我建議看一下INotifyDataErrorInfo界面。這是實作屬性驗證的推薦方法,并允許以非常簡單的方式提供 UI 錯誤反饋。
uj5u.com熱心網友回復:
我在 Windows 表單中執行此操作(我打開了一個測驗 Windows 表單專案),但在 WPF 中應該大致相同。我在表單上放置了一個按鈕、一個標簽和一個文本框。然后我寫了這段代碼:
private async void button1_Click(object sender, EventArgs e)
{
var result = await ValidateTextBox();
if (result != null)
{
label1.Text = result;
return;
}
var intResult = await ReadTextBox();
label1.Text = intResult.ToString();
await IncrementTextBox();
intResult = await ReadTextBox();
label1.Text = intResult.ToString();
}
private async Task<string> ValidateTextBox()
{
await Task.Delay(2000);
if (!int.TryParse(textBox1.Text, out _)) {
return "Not Valid";
}
//otherwise
return null;
}
private async Task<int> ReadTextBox()
{
await Task.Delay(3000);
if (!int.TryParse(textBox1.Text, out var result))
{
throw new Exception("Don't do that");
}
return result;
}
private async Task IncrementTextBox()
{
await Task.Delay(3000);
if (!int.TryParse(textBox1.Text, out var result))
{
throw new Exception("Don't do that");
}
textBox1.Text = (result 1).ToString();
}
如果您int在文本框中鍵入不屬于的內容并按下按鈕,則幾秒鐘過去,然后Not Valid顯示在標簽中。
如果那里有一個數字,那么會有一個暫停,這個數字會顯示在標簽中。然后再次暫停,文本框編號將增加 1。最后,再次暫停后,標簽將顯示增加的值。
請注意,這一切都在單個執行緒上運行。但是,盡管存在所有延遲,UI 始終保持回應。
在每個函式的開頭和按鈕單擊處理程式中每個等待之后的行上放置斷點。逐步完成(而不是進入)整個程序,您將看到等待如何創建延續
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/359037.html
