Skip to content

Conversation

@chanderlud
Copy link

I worked with @steeley21 on this assignment. We completed the extra credit.

Copilot AI review requested due to automatic review settings December 1, 2025 23:06
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR implements asynchronous ping functionality with cancellation support and progress reporting for a C# assignment. The implementation includes both basic async patterns and advanced features like parallel execution and long-running tasks.

Key Changes:

  • Implemented RunTaskAsync, RunAsync (multiple overloads), and RunLongRunningAsync methods with proper async/await patterns and cancellation token support
  • Added synchronization mechanisms to handle parallel ping operations safely
  • Implemented progress reporting using IProgress<T> for extra credit
  • Updated build configuration to use latest C# language version and enhanced code analysis

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated no comments.

File Description
README.md Updated checklist to mark all requirements and extra credit as completed
Assignment/Directory.Build.props Modified language version from 13.0 to "latest" and added analysis configuration
Assignment/Assignment/PingProcess.cs Implemented all required async methods with cancellation support, parallel execution with thread-safe synchronization, and progress reporting
Assignment/Assignment.Tests/PingProcessTests.cs Added comprehensive test coverage for all implemented async methods including cancellation, parallel execution, and progress reporting

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@github-actions
Copy link

github-actions bot commented Dec 1, 2025

Summary

Summary
Generated on: 12/01/2025 - 23:54:16
Coverage date: 12/01/2025 - 23:54:14
Parser: MultiReport (2x Cobertura)
Assemblies: 1
Classes: 2
Files: 1
Line coverage: 47.1% (83 of 176)
Covered lines: 83
Uncovered lines: 93
Coverable lines: 176
Total lines: 255
Branch coverage: 41% (32 of 78)
Covered branches: 32
Total branches: 78
Method coverage: Feature is only available for sponsors
Tag: 507_19841548346

Coverage

Assignment - 47.1%
Name Line Branch
Assignment 47.1% 41%
Assignment.PingProcess 46.8% 41%
Assignment.PingResult 100%

Copy link

@katmilton katmilton left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implement PingProcess' public Task RunTaskAsync(string hostNameOrAddress) ✔
First implement public void RunTaskAsync_Success() test method to test PingProcess.RunTaskAsync() using "localhost". ✔
Do NOT use async/await in this implementation. ✔
Implement PingProcess' async public Task RunAsync(string hostNameOrAddress) ✔
First implement the public void RunAsync_UsingTaskReturn_Success() test method to test PingProcess.RunAsync() using "localhost" without using async/await. ✔
Also implement the async public Task RunAsync_UsingTpl_Success() test method to test PingProcess.RunAsync() using "localhost" but this time DO using async/await. ✔
Add support for an optional cancellation token to the PingProcess.RunAsync() signature. ✔
Inside the PingProcess.RunAsync() invoke the token's ThrowIfCancellationRequested() method so an exception is thrown. ✔
Test that, when cancelled from the test method, the exception thrown is an AggregateException ✔
with a TaskCanceledException inner exception ✔
using the test methods RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrapping ✔and RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrappingTaskCanceledException ✔ respectively.
Complete/fix AND test async public Task RunAsync(IEnumerable hostNameOrAddresses, CancellationToken cancellationToken = default) which executes ping for an array of hostNameOrAddresses (which can all be "localhost") in parallel, adding synchronization if needed. ✔ NOTE:
The order of the items in the stdOutput is irrelevant and expected to be intermingled.
StdOutput must have all the ping output returned (no lines can be missing) even though intermingled. ✔
Implement AND test public Task RunLongRunningAsync(ProcessStartInfo startInfo, Action<string?>? progressOutput, Action<string?>? progressError, CancellationToken token) using Task.Factory.StartNew() and invoking RunProcessInternal with a TaskCreation value of TaskCreationOptions.LongRunning and a TaskScheduler value of TaskScheduler.Current. Returning a Task is also okay. NOTE: This method does NOT use Task.Run.

Extra Credit
Test and implement PingProcess.RunAsync(System.IProgress progess) so that you can capture the output as it occurs rather than capturing the output only when the process finishes. ✔

Fundamentals
Place all shared project properties into a Directory.Build.Props file.
Place all shared project items into a Directory.Build.targets file.
Ensure nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, consider using Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

Looks great y'all! Good work.

Copy link

@BillMillerCoding BillMillerCoding left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implement PingProcess' public Task RunTaskAsync(string hostNameOrAddress) ✔
First implement public void RunTaskAsync_Success() test method to test PingProcess.RunTaskAsync() using "localhost". ✔
Do NOT use async/await in this implementation. ✔
Implement PingProcess' async public Task RunAsync(string hostNameOrAddress) ✔
First implement the public void RunAsync_UsingTaskReturn_Success() test method to test PingProcess.RunAsync() using "localhost" without using async/await. ✔
Also implement the async public Task RunAsync_UsingTpl_Success() test method to test PingProcess.RunAsync() using "localhost" but this time DO using async/await. ✔
Add support for an optional cancellation token to the PingProcess.RunAsync() signature. ✔ Inside the PingProcess.RunAsync() invoke the token's ThrowIfCancellationRequested() method so an exception is thrown. ✔ Test that, when cancelled from the test method, the exception thrown is an AggregateException ✔ with a TaskCanceledException inner exception ✔ using the test methods RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrapping ✔and RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrappingTaskCanceledException ✔ respectively.
Complete/fix AND test async public Task RunAsync(IEnumerable hostNameOrAddresses, CancellationToken cancellationToken = default) which executes ping for an array of hostNameOrAddresses (which can all be "localhost") in parallel, adding synchronization if needed. ✔ NOTE:
The order of the items in the stdOutput is irrelevant and expected to be intermingled.
StdOutput must have all the ping output returned (no lines can be missing) even though intermingled. ✔
Implement AND test public Task RunLongRunningAsync(ProcessStartInfo startInfo, Action<string?>? progressOutput, Action<string?>? progressError, CancellationToken token) using Task.Factory.StartNew() and invoking RunProcessInternal with a TaskCreation value of TaskCreationOptions.LongRunning and a TaskScheduler value of TaskScheduler.Current. Returning a Task is also okay. NOTE: This method does NOT use Task.Run. ✔
Super cool implementation of FakePingProcess
Place all shared project properties into a Directory.Build.Props file.
Place all shared project items into a Directory.Build.targets file.
Ensure nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, consider using Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

@PigPig-SDK
Copy link

Implement PingProcess' public Task RunTaskAsync(string hostNameOrAddress) ✔
First implement public void RunTaskAsync_Success() test method to test PingProcess.RunTaskAsync() using "localhost". ✔
Do NOT use async/await in this implementation. ✔
Implement PingProcess' async public Task RunAsync(string hostNameOrAddress) ✔
First implement the public void RunAsync_UsingTaskReturn_Success() test method to test PingProcess.RunAsync() using "localhost" without using async/await. ✔
Also implement the async public Task RunAsync_UsingTpl_Success() test method to test PingProcess.RunAsync() using "localhost" but this time DO using async/await. ✔
Add support for an optional cancellation token to the PingProcess.RunAsync() signature. ✔ Inside the PingProcess.RunAsync() invoke the token's ThrowIfCancellationRequested() method so an exception is thrown. ✔ Test that, when cancelled from the test method, the exception thrown is an AggregateException ✔ with a TaskCanceledException inner exception ✔ using the test methods RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrapping ✔and RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrappingTaskCanceledException ✔ respectively.
Complete/fix AND test async public Task RunAsync(IEnumerable hostNameOrAddresses, CancellationToken cancellationToken = default) which executes ping for an array of hostNameOrAddresses (which can all be "localhost") in parallel, adding synchronization if needed. ✔ NOTE:
The order of the items in the stdOutput is irrelevant and expected to be intermingled.
StdOutput must have all the ping output returned (no lines can be missing) even though intermingled. ✔
Implement AND test public Task RunLongRunningAsync(ProcessStartInfo startInfo, Action<string?>? progressOutput, Action<string?>? progressError, CancellationToken token) using Task.Factory.StartNew() and invoking RunProcessInternal with a TaskCreation value of TaskCreationOptions.LongRunning and a TaskScheduler value of TaskScheduler.Current. Returning a Task is also okay. NOTE: This method does NOT use Task.Run.
Fundamentals
Place all shared project properties into a Directory.Build.Props file. ✔
Place all shared project items into a Directory.Build.targets file.
Ensure nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, consider using Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

@c-stanton
Copy link

Implement PingProcess' public Task RunTaskAsync(string hostNameOrAddress) ✔
First implement public void RunTaskAsync_Success() test method to test PingProcess.RunTaskAsync() using "localhost". ✔
Do NOT use async/await in this implementation. ✔
Implement PingProcess' async public Task RunAsync(string hostNameOrAddress) ✔
First implement the public void RunAsync_UsingTaskReturn_Success() test method to test PingProcess.RunAsync() using "localhost" without using async/await. ✔
Also implement the async public Task RunAsync_UsingTpl_Success() test method to test PingProcess.RunAsync() using "localhost" but this time DO using async/await. ✔
Add support for an optional cancellation token to the PingProcess.RunAsync() signature. ✔ Inside the PingProcess.RunAsync() invoke the token's ThrowIfCancellationRequested() method so an exception is thrown. ✔ Test that, when cancelled from the test method, the exception thrown is an AggregateException ✔ with a TaskCanceledException inner exception ✔ using the test methods RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrapping ✔and RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrappingTaskCanceledException ✔ respectively.
Complete/fix AND test async public Task RunAsync(IEnumerable hostNameOrAddresses, CancellationToken cancellationToken = default) which executes ping for an array of hostNameOrAddresses (which can all be "localhost") in parallel, adding synchronization if needed. ✔ NOTE:
The order of the items in the stdOutput is irrelevant and expected to be intermingled.
StdOutput must have all the ping output returned (no lines can be missing) even though intermingled. ✔
Implement AND test public Task RunLongRunningAsync(ProcessStartInfo startInfo, Action<string?>? progressOutput, Action<string?>? progressError, CancellationToken token) using Task.Factory.StartNew() and invoking RunProcessInternal with a TaskCreation value of TaskCreationOptions.LongRunning and a TaskScheduler value of TaskScheduler.Current. Returning a Task is also okay. NOTE: This method does NOT use Task.Run. ✔
Super cool implementation of FakePingProcess
Place all shared project properties into a Directory.Build.Props file.
Place all shared project items into a Directory.Build.targets file.
Ensure nullable reference types is enabled ✔
Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
and enabled .NET analyzers for both projects ✔
For this assignment, consider using Assert.AreEqual() (the generic version) ✔
All of the above should be unit tested ✔
Choose simplicity over complexity ✔

Copy link
Collaborator

@Joshua-Lester3 Joshua-Lester3 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instructions

  1. Implement PingProcess' public Task<PingResult> RunTaskAsync(string hostNameOrAddress)
    • First implement public void RunTaskAsync_Success() test method to test PingProcess.RunTaskAsync() using "localhost". ✔
    • Do NOT use async/await in this implementation. ✔
  2. Implement PingProcess' async public Task<PingResult> RunAsync(string hostNameOrAddress)
    • First implement the public void RunAsync_UsingTaskReturn_Success() test method to test PingProcess.RunAsync() using "localhost" without using async/await. ✔
    • Also implement the async public Task RunAsync_UsingTpl_Success() test method to test PingProcess.RunAsync() using "localhost" but this time DO using async/await. ✔
  3. Add support for an optional cancellation token to the PingProcess.RunAsync() signature. ✔
    Inside the PingProcess.RunAsync() invoke the token's ThrowIfCancellationRequested() method so an exception is thrown. ✔
    Test that, when cancelled from the test method, the exception thrown is an AggregateException ✔ with a TaskCanceledException inner exception ✔ using the test methods RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrapping ✔and RunAsync_UsingTplWithCancellation_CatchAggregateExceptionWrappingTaskCanceledException ✔ respectively.
  4. Complete/fix AND test async public Task<PingResult> RunAsync(IEnumerable<string> hostNameOrAddresses, CancellationToken cancellationToken = default) which executes ping for an array of hostNameOrAddresses (which can all be "localhost") in parallel, adding synchronization if needed. ✔
    NOTE:
    • The order of the items in the stdOutput is irrelevant and expected to be intermingled.
    • StdOutput must have all the ping output returned (no lines can be missing) even though intermingled. ✔
  5. Implement AND test public Task<int> RunLongRunningAsync(ProcessStartInfo startInfo, Action<string?>? progressOutput, Action<string?>? progressError, CancellationToken token) using Task.Factory.StartNew() and invoking RunProcessInternal with a TaskCreation value of TaskCreationOptions.LongRunning and a TaskScheduler value of TaskScheduler.Current. Returning a Task<PingResult> is also okay.
    NOTE: This method does NOT use Task.Run.

Extra Credit

  • Test and implement PingProcess.RunAsync(System.IProgress<T> progess) so that you can capture the output as it occurs rather than capturing the output only when the process finishes. ✔

Fundamentals

  • Place all shared project properties into a Directory.Build.Props file.
  • Place all shared project items into a Directory.Build.targets file.
  • Ensure nullable reference types is enabled ✔
  • Ensure that you turn on code analysis for all projects(EnableNETAnalyzers) ✔
  • Set LangVersion and the TargetFramework to the latest released versions available (preview versions optional) ✔
  • and enabled .NET analyzers for both projects ✔
  • For this assignment, consider using Assert.AreEqual<T>() (the generic version) ✔
  • All of the above should be unit tested ✔
  • Choose simplicity over complexity ✔

Looks good!

{
Task<PingResult> task = RunTaskAsync(hostNameOrAddress, cancellationToken);
PingResult result = await task.WaitAsync(cancellationToken);
cancellationToken.ThrowIfCancellationRequested();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this line is needed, with the line before already in place. WaitAsync will handle this for you AFAIK.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot there's a requirement saying to call this. I'd probably prefer one or the other though.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants