Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
108 views
in Technique[技术] by (71.8m points)

c# - Interrupt calling thread when exception in child task

I have the following scenario:

I have a plugin class (unfortunately synchronous and that's out of my control) which runs automation scripts. At startup, a task is started which runs in the background continuously until the user stops it. As this task runs, it is parsing streaming incoming data from a serial port and continuously updating a list of responses. In parallel, the script will be changing some other values and monitoring how the responses react.

My problem is this -- it is possible that the parser could throw an exception and that renders any of the remaining script invalid. But, I can't find a good way to interrupt the script (i.e. void Main() below) should this parallel task throw. If I wait until my script is done, and then await the task, I do get the exception, but by then there is potentially a lot of time wasted. So I'm looking for better ways to interrupt the script that is running should the parallel task error. I've tried posting on the initial synchronization context but with no luck as well. I've parred down an example below to simulate a similar scenario

public class Test : TestPlugin
{
    Task _t;
    List<string> data = new List();

    public Test(){ }
    
    public override void Cleanup()
    {
        //_t.Wait();
    }
    
    public override void Main()
    {
        // i want this to be interrupted if the polling task started in startup throws. 
        //Right here simulates running test steps, 
        //any of which can access the data that's been updated by the "background" task at any time
        try
        {
            int i = 0;
            while (i < 10)
            {
                Task.Delay(1000).Wait();
                Console.WriteLine("step" + i + "Latest: " + data.latest());
                i++;
            }
        }
        catch(Exception ex)
        {
            Console.WriteLine("EXCEPTION");
        }
    }

    public override void Setup()
    {
        _t = Task.Run(async () =>
        {
            int i =0;
            while (i < 10)
            {
                await Task.Delay(200);
                Console.WriteLine(i);
                i++;
                //i would parse incoming data and add to array here
                data.add(i);
                if (i > 3) throw new Exception("UH OH");
            }
        });
    }
}
question from:https://stackoverflow.com/questions/65926798/interrupt-calling-thread-when-exception-in-child-task

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You could investigate the Task.ContinueWith method on the calling task code. this ContinueWith allows for a delegate callback that gets triggered on completion and/or exceptions. so perhaps within the ContinueWith delegate, do a check if the task completes successfully, if not then raise a new exception there appending the thrown exception passed to the delegate.

You can use the code below as an example:

Task t1 = factory.StartNew(() =>
{
    DoSomething();
}).ContinueWith((t2) =>
{
    if (t2.IsCanceled)
        DoSomethingWhenCancelled();
    else if (t2.IsFaulted)
        DoSomethingOnError(t1.Exception);
    else
        DoSomethingWhenComplete();
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...