On a WinForm, I need to continuously read data from a source (USB device in my case) and display the data in labels. The reading should started on command (button_click) and stopped on another button click or in the form_closing method. I meanwhile found out that I need to use Task.Factory
for this since I can create a CancellationToken
there. Here is my (example) code so far:
public partial class Form1 : Form
{
CancellationTokenSource m_CancellationSource;
Task m_USBReaderTask;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
m_CancellationSource = new CancellationTokenSource();
m_USBReaderTask = Task.Factory.StartNew(() => doAsync(m_CancellationSource.Token), m_CancellationSource.Token);
}
private void doAsync(CancellationToken ct)
{
InitUSBReader();
while (!ct.IsCancellationRequested)
{
int[] data=ReadUSB();
this.Invoke((MethodInvoker)delegate
{
lbOut1.Text = data[0].ToString();
lbOut2.Text = data[1].ToString();
lbOut3.Text = data[2].ToString();
//... and so on...
});
}
CleanupUSBReader(); //this is never happening
}
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
if (null != m_CancellationSource)
{
m_CancellationSource.Cancel();
m_USBReaderTask.Wait(); // this always hangs.
}
}
}
Obviously I am facing two problems:
- When the
CancellationToken
is set the task is aborted but I need to clean up, I just want to end the 'while' loop. (or does it crash and no error message?) - In the
FormClosing
event, I need to wait until the cleaning up has finished but it blocks endlessly.
Beside my two problems, is my approach correct at all or is there a more elegant way to achieve my goals? Thanks