Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Cancellationtoken异常未执行_C#_Wpf_Cancellationtokensource_Cancellation Token - Fatal编程技术网

C# Cancellationtoken异常未执行

C# Cancellationtoken异常未执行,c#,wpf,cancellationtokensource,cancellation-token,C#,Wpf,Cancellationtokensource,Cancellation Token,我需要通过单击按钮取消以下异步方法 这就是我所尝试的: private CancellationTokenSource cts; private async Task<bool> ValidateFtpAsync() { cts = new CancellationTokenSource(); CancellationToken token = cts.Token; try {

我需要通过单击按钮取消以下异步方法

这就是我所尝试的:

private CancellationTokenSource cts;

    private async Task<bool> ValidateFtpAsync()
    {

        cts = new CancellationTokenSource();
        CancellationToken token = cts.Token;
        try
        {
            return await Task.Run(
                    () =>
                    {

                        token.ThrowIfCancellationRequested();

                        Global_Variables.DoingStuff = true;

                        if (File.Exists("settings.xml"))
                        {
                            var xs = new XmlSerializer(typeof(Information));
                            using (var read = new FileStream("settings.xml", FileMode.Open, FileAccess.ReadWrite, FileShare.ReadWrite))
                            {

                                token.ThrowIfCancellationRequested();

                                Information info = (Information)xs.Deserialize(read);

                                try
                                {
                                    var DecryptedInfo = FileCryptoDecryptor.ReadEncryptedConfiguration("hakuna.xml.aes", Global_Variables.AppPassword);
                                    string DecryptedFTPPass = EncryDecryptor.Decrypt(DecryptedInfo.FtpPassword, "blablabla");
                                    token.ThrowIfCancellationRequested();
                                    return General_Functions.isValidConnection(info.HDSynologyIP, info.FtpUsername, DecryptedFTPPass);
                                }
                                catch (Exception ex)
                                {
                                    MessageBox.Show(ex.ToString());
                                }
                            }
                            return false;
                        }
                        else
                        {
                            MessageBox.Show("Missing settings file.");
                            return false;
                        }
                    }, token);
        }
        catch(OperationCanceledException)
        {
            MessageBox.Show("Canceled test");
            return false;
        }
    }

    private void cancelButton_Click(object sender, RoutedEventArgs e)
    {
        cts.Cancel();
    }
这个函数不是异步的,执行起来需要花费很多时间,这会导致问题吗

看起来像这样:

 public static bool isValidConnection(string url, string user, string password)
    {
        try
        {
            FtpClient client = new FtpClient(url);
            client.Credentials = new NetworkCredential(user, password);
            client.SocketPollInterval = 60000;
            client.ConnectTimeout = 60000;
            client.ReadTimeout = 60000;
            client.DataConnectionConnectTimeout = 60000;
            client.DataConnectionReadTimeout = 60000;
            client.Connect();

            bool IsItConnected = client.IsConnected;

            if (IsItConnected == true)
            {
                client.Disconnect();
                client.Dispose();
                return true;
            }
            else
            {
                client.Disconnect();
                client.Dispose();
                return false;
            }

        }
        catch(Exception ex)
        {
            LogWriter loger = new LogWriter(ex.ToString());
            return false;
        }
    }
//编辑


Ftpclient来自FluentFTP库:

首先,检查连接是否有效的方法根本不考虑取消令牌。如果它在执行网络操作时被阻止,即使您取消令牌,在它完成之前也不会发生任何事情。 如果FTP客户端占用了整个处理时间的大部分,并且没有接受CancellationToken的异步重载,那么它实际上是不可取消的,并且丢掉了您期望从CancellationToken中获得的所有优势

其次,如果取消发生在最里面的try块中,则您的
catch(Exception)
部分会抑制操作canceledexceptions。如果异常为OperationCanceledException,则应重新显示该异常

                           try
                            {
                                var DecryptedInfo = FileCryptoDecryptor.ReadEncryptedConfiguration("hakuna.xml.aes", Global_Variables.AppPassword);
                                string DecryptedFTPPass = EncryDecryptor.Decrypt(DecryptedInfo.FtpPassword, "blablabla");
                                token.ThrowIfCancellationRequested();
                                return General_Functions.isValidConnection(info.HDSynologyIP, info.FtpUsername, DecryptedFTPPass);
                            }
                            catch (Exception ex) when (!(ex is OperatiomCanceledException))
                            {
                                MessageBox.Show(ex.ToString());
                            }

首先,检查连接是否有效的方法根本不考虑取消令牌。如果它在执行网络操作时被阻止,即使您取消令牌,在它完成之前也不会发生任何事情。 如果FTP客户端占用了整个处理时间的大部分,并且没有接受CancellationToken的异步重载,那么它实际上是不可取消的,并且丢掉了您期望从CancellationToken中获得的所有优势

其次,如果取消发生在最里面的try块中,则您的
catch(Exception)
部分会抑制操作canceledexceptions。如果异常为OperationCanceledException,则应重新显示该异常

                           try
                            {
                                var DecryptedInfo = FileCryptoDecryptor.ReadEncryptedConfiguration("hakuna.xml.aes", Global_Variables.AppPassword);
                                string DecryptedFTPPass = EncryDecryptor.Decrypt(DecryptedInfo.FtpPassword, "blablabla");
                                token.ThrowIfCancellationRequested();
                                return General_Functions.isValidConnection(info.HDSynologyIP, info.FtpUsername, DecryptedFTPPass);
                            }
                            catch (Exception ex) when (!(ex is OperatiomCanceledException))
                            {
                                MessageBox.Show(ex.ToString());
                            }

如果在
MessageBox.Show上放置断点,当您单击按钮时,调试器是否会停止?你可能看不到消息,因为它在子线程中运行?@MickyD没有,但当我足够快地单击时,我会得到带有“操作被取消”的messagebox,这就是为什么如果你在
messagebox上设置断点,我怀疑返回函数。Show
当你单击按钮时,调试器是否停止在那里?你可能看不到消息,因为它在子线程中运行?@MickyD没有,但当我足够快地单击时,我得到带有“操作被取消”的messagebox,这就是我怀疑返回函数的原因