[英]Using threads for external communication (PC -> RS485 device)
我正在使用NModbus4通過ModbusRTU(RS485)進行通信。 我的程序需要不斷地從設備獲取數據,該設備經常斷開連接。 當設備斷開連接時,我在等待期間收到超時異常(這是可以理解的),因為程序等待設備響應,因此程序運行緩慢(正在瀏覽表格,按下按鈕等)。
是否可以將Modbus連接移動到單獨的線程以與用戶界面並行處理(或者有更好的選擇)?
如果是這樣,請幫我舉一個簡單的示例,說明如何與事件相關聯(我正在通過事件傳遞設備數據和信息以顯示數據)。
樣例代碼:
public MainGui()
{
InitializeComponent();
DataTransport DataManagment = new DataTransport(); //DataTransport is a class that handles communication and publishes event 'DataSent'
DataManagment.DataSent += new EventHandler<DataSentArgs>(UnpackData);
}
private void slaveDataReqTimer_Tick(object sender, EventArgs e)
{
//Timer that is responsible for fetching data
new Thread(() =>
{
Thread.CurrentThread.IsBackground = true;
DataManagment.RequestData();
}).Start();
}
public void UnpackData(object sender, DataSentArgs e)
{
//Doing some stuff when data arrives
}
這段代碼的問題是我無法將事件從新線程傳遞到當前線程(此外,我不知道使用線程的方法是否正確)。
我只是從C#和.NET開始,所以示例代碼可能與標准約定不符-抱歉。
為此,線程是一個太低級的原語-我建議研究任務,並盡可能避免一般地使用線程。
這是您情況下的代碼。 DataManagement.RequestData調用發生在不同的線程上,該線程取自線程池,但是此后立即進入主線程的上下文,因此您不必執行任何同步/封送處理等。 如果ProcessData方法也很慢,則可以執行與DataManagement.RequestData相同的操作-在任務上執行它。 再一次,將不需要同步化。
public MainWindow()
{
InitializeComponent();
var cts = new CancellationTokenSource();
Unloaded += delegate { cts.Cancel(); };
ProcessData(cts.Token);
}
async void ProcessData(CancellationToken ct)
{
try
{
while (true)
{
ct.ThrowIfCancellationRequested();
try
{
var dataItem = await Task.Run(() => DataManagement.RequestData());
ProcessData(dataItem);
}
catch(Exception_Thrown_By_RequestData e)
{
// decide what do - either break the loop or continue if
// this is not a heavy faiulre
}
await Task.Delay(DelayTime, ct);
}
}
catch (TaskCanceledException) { }
catch (OperationCanceledException) { }
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.