[英]Continuous polling using Tasks
這是我一直使用Threads / BackgroundWorker的東西,但我正在嘗試遷移到Task的做事方式。
假設我有一個第三方SDK用於從USB端口讀取字節。 如果沒有讀取字節,則讀取調用將阻塞並在100 ms后超時,返回null。 如果讀取字節,它會立即返回,返回讀取字節的byte []數組。
所以我基本上需要一遍又一遍地輪詢,並通過調用解析函數對接收到的字節采取措施。 它是一個WPF應用程序,因此返回的字節應該能夠傳遞給UI線程函數。
這樣做的正確方法是什么? 這是我到目前為止,它似乎工作,但我想確保它是使用TPL做事的正確方法:
private void _connectUsbButton_Click(object sender, RoutedEventArgs e)
{
ListenForUsbMessagesAsync();
}
private async void ListenForUsbMessagesAsync()
{
while (true)
{
byte[] readBytes = await ReadBytesAsync();
Parse(readBytes);
}
}
private Task<byte[]> ReadBytesAsync()
{
Task<byte[]> readBytesTask = Task.Run(() =>
{
byte[] bytes;
do
{
bytes = ReadBytes();
} while (bytes == null);
return bytes;
});
return readBytesTask;
}
private byte[] ReadBytes()
{
byte[] readBytes = _usbSdk.ReadBytes(); //100ms timeout (returns null if no bytes read)
return readBytes;
}
對我來說沒問題,這里只有一些建議:
private async Task ListenForUsbMessagesAsync(CancellationToken token)
{
while (true)
{
byte[] readBytes = await ReadBytesAsync();
Parse(readBytes);
token.ThrowIfCancellationRequested();
}
}
在其他地方,比如在WPF Window。中存儲這個
var tokenSource = new System.Threading.CancellationTokenSource();
最后像這樣調用你的函數
private void _connectUsbButton_Click(object sender, RoutedEventArgs e)
{
ListenForUsbMessagesAsync(tokenSource.Token);
}
這樣您就可以隨時通過呼叫取消您的任務
tokenSource.Cancel()
或者,如果您不想使用“任務”,則可以生成新的Thread並傳入Dispatcher對象。 通過這種方式,新創建的Thread可以安全地將內容解壓到UI線程上。
由於您的輪詢任務可能會運行很長時間,因此您應該考慮在專用線程中運行它。
您可以通過在創建輪詢任務時傳遞TaskCreationOptions.LongRunning標志來實現此目的 。
像這樣:
Task<byte[]> readBytesTask = Task.Factory.StartNew(() =>
{
byte[] bytes;
do
{
bytes = ReadBytes();
} while (bytes == null);
return bytes;
}, TaskCreationOptions.LongRunning);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.