Click here to Skip to main content
15,881,424 members
Please Sign up or sign in to vote.
1.00/5 (3 votes)
Here is the demo wpf code:
C#
private CancellationTokenSource _cancel;

        public MainWindow()
        {
            InitializeComponent();

            _cancel = new CancellationTokenSource();
            var task = new Task(() =>
            {
                try
                {
                    _cancel.Token.Register(() =>
                    {
                        _cancel.Token.ThrowIfCancellationRequested();
                    });
                    Thread.Sleep(100000);
                }
                catch (Exception)
                {
                }
            });

            task.Start();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _cancel.Cancel();
        }


The TaskCancel exception will throw in main thread, how can I do to throw TaskCancelException in the task thread and be catched? still cancel task by click button:)
Thanks!
Posted

1 solution

,The only exception you can seed into some working thread totally asynchronously to this thread is the System.Threading.ThreadAbortException, which is done only by runtime system as a result of thread abort:
https://msdn.microsoft.com/en-us/library/system.threading.threadabortexception%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.threading.thread.abort%28v=vs.110%29.aspx[^].

This technique is related to exception seeding.

This approach is quite adequate but is considered as dangerous my many; I, as a person who understands how it works under the hood, use it but would just warn that using it requires good understanding of what you are doing. Please see my past answers,
Close correcly the thread inside a dll[^],
Problem with creating Process from dedicated thread[^].

All other exceptions can only use cooperative approach; they should be thrown in the same thread. To, understand why, some deeper understanding of exception mechanism is needed. Please see my past answers:
Does Exception in C# Constructor Cause Caller Assignment to Fail?[^],
where was stored .net exceptions in operating system[^].

The example of such cooperative approach is the mechanism of System.Threading.CancellationToken you already use:
https://msdn.microsoft.com/en-us/library/system.threading.cancellationtoken%28v=vs.110%29.aspx[^],
https://msdn.microsoft.com/en-us/library/system.threading.cancellationtokensource%28v=vs.110%29.aspx[^].

You only request the cancellation from some other thread (main thread), but exception is thrown in the same very thread which should be cancelled. Please see the code samples in the articles referenced above.

—SA
 
Share this answer
 
Comments
[no name] 27-Feb-15 15:58pm    
One answer again, worth to bookmark and 5.
Bruno
Sergey Alexandrovich Kryukov 27-Feb-15 18:24pm    
Thank you, Bruno.
—SA
eric881027 27-Feb-15 22:10pm    
Thanks for your informative answer!
But in the articles the cancel is called inside of the task, of course, the exception will be throw by the task thread, and if you call the cancel() by click button, the exception will be throw in _cancel.Cancel()(main thread).
As you said, every thread has an exception stack(if I understand correctly),and exception will be "created" in the thread who raise it right, it seems like there is no way one thread can throw an exception in the other thread except abort the other thread directly.
Maybe I can implement it like this:
Task.Run(() =>
{
try
{
var currentThread = Thread.CurrentThread;
_cancel.Token.Register(currentThread.Abort);
DoWork();
}
catch (Exception)
{
throw;
}
})

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