Click here to Skip to main content
15,867,686 members
Please Sign up or sign in to vote.
4.50/5 (2 votes)
See more:
Obviously, there is tons of stuff online about .NET's growing number of ways to multithread code. And that's the problem - working out not just which one to use but how to avoid unnecessarily (and possibly dangerously) mixing approaches.

My requirements seem straightforward enough:
1. I want to start a background task (a Bluetooth reconnection) from an event handler.
2. I want the event handler to end quickly.
3. I want to be able to run some code when the background work completes.
4. I want to catch any exceptions.
5. I want to avoid nightmares caused by the numerous warnings to avoid async void.

I'd be grateful for advice about to satisfy these requirements with readable and safe code.

What I have tried:

What I suspect is a mix-n-match hotchpotch of the available options.

Also in an attempt to use the BackgroundWorker suggested by @OriginalGriff, I now have something that looks like this:

// Event handler for when Bluetooth connection is lost.
void BLEAdapter_DeviceConnectionLost( object sender, DeviceErrorEventArgs e )
{
	_reconnectBLEWorker = new BackgroundWorker();
	_reconnectBLEWorker.DoWork += ReconnectBLEWorker_DoWork;
	_reconnectBLEWorker.RunWorkerCompleted += ReconnectBLEWorker_RunWorkerCompleted;
	_reconnectBLEWorker.RunWorkerAsync();
}

// BackgroundWorker work.
async void ReconnectBLEWorker_DoWork( object sender, DoWorkEventArgs e )
{
	int retryCount = 0;
	while( !_bluetoothConnected && retryCount < 10 )
	{
		await KnownDeviceReconnection();
		++retryCount;
	}
	// Act accordingly here, depending on whether Bluetooth connected okay.
}

// Wrap async code so exceptions can be caught and these don't go up into the calling async void event handler.
async Task KnownDeviceReconnection()
{
	try
	{
		IDevice device = await App.BLE.Adapter.ConnectToKnownDeviceAsync( _lastConnectedDeviceGuid );
	}
	catch( Exception ex )
	{
		// Log error.
	}
}

// Event handler for when BackgroundWorker finishes.
void ReconnectBLEWorker_RunWorkerCompleted( object sender, RunWorkerCompletedEventArgs e )
{
	// This happens immediately.
}


This is not working. Clearly I am misunderstanding how async/await works because I just don't get why, in the code above, the BackgroundWorker work thread ends immediately.
Posted
Updated 2-Oct-20 0:52am
v2
Comments
BillWoodruff 29-Sep-20 8:53am    
"What I suspect is a mix-n-match hotchpotch of the available options."

Upvoted for honesty :)

1 solution

Use a BackgroundWorker - it can report back to the UI thread as necessary:
C#
private void FrmMain_Shown(object sender, EventArgs e)
    {
    BackgroundWorker work = new BackgroundWorker();
    work.WorkerReportsProgress = true;
    work.DoWork += Work_DoWork;
    work.ProgressChanged += Work_ProgressChanged;
    work.RunWorkerCompleted += Work_RunWorkerCompleted;
    work.RunWorkerAsync();
    }

private void Work_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
    {
    // Do whatever is necessary after worker complete
    }

private void Work_ProgressChanged(object sender, ProgressChangedEventArgs e)
    {
    // Do display updates as connection happens, or gives results.
    }

private void Work_DoWork(object sender, DoWorkEventArgs e)
    {
    // Do the actual connection and subsequent processing here.
    }
 
Share this answer
 
Comments
johannesnestler 29-Sep-20 11:08am    
old but simplest solution for this in .NET UI - 5ed
Patrick Skelton 30-Sep-20 4:49am    
Ooo... I had forgotten reading about that many moons ago. I like it. (Only thing my OCD is struggling with is the fact that these are the first FnAsync() methods I've come across that are not awaitable, but I guess that would kind-of lead me full-circle.) Thank you!
OriginalGriff 30-Sep-20 5:19am    
You're welcome!
Patrick Skelton 2-Oct-20 6:54am    
Mmm... I've bumped into problems with this. I am clearly seriously misunderstanding something. I'm hoping you (or someone else) can tell me what I am doing wrong.
OriginalGriff 2-Oct-20 7:15am    
And how do you think we should do that, given I can't see your screen? :laugh:

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900