简体   繁体   English

如何杀死(不取消)已经被调用的异步任务?

[英]How to kill (not cancel) a Asynchronous Task which has already been called?

I am developing an application that sends and receives commands via SerialPort. 我正在开发一个通过SerialPort发送和接收命令的应用程序。 Sometimes the hardware I am communicating with does not respond, how do I stop my application from waiting for a response? 有时与我通信的硬件没有响应,如何停止应用程序等待响应? Because it is not allowing me to retry sending and receiving commands. 因为不允许我重试发送和接收命令。 I get a "Access to the port 'COM#' is denied." 我收到“拒绝访问端口'COM#'。” exception when I call the sendRecvCMDAsync() function a second time. 当我第二次调用sendRecvCMDAsync()函数时发生异常。

Here is my SerialPort communicaion code, 这是我的SerialPort通信代码,

        public async Task<List<String>> sendRecvCMDAsync(String COMPort, String FW_CMD, List<String> SendParamList, CancellationToken ct)
    {
        SL_Port = new SerialPort();
        try
        {
            if (COMPort != "")
            {
                SL_Port.PortName = COMPort;
            }
            else
            {
                //show a message box;
            }

            if (SL_Port.IsOpen)
            {
                SL_Port.Dispose();
                SL_Port.Close();
            }
            SL_Port.Close();
            SL_Port.Open();
            SL_Port.WriteLine(FW_CMD);
            _continue = true;
            Array.Clear(buffer, 0, buffer.Length);
            int count = 0;
            while (_continue)
            {
                mess = "";
                Task<int> bytes = SL_Port.BaseStream.ReadAsync(buffer, count, buffer.Length - count, ct);
                int bytesCount = await bytes;//I need to kill this after its started, because it is not alowing me to access the COM port unless it completes.
                count = bytesCount + count;
                mess = Encoding.ASCII.GetString(buffer).TrimEnd('\0');
                if (mess.Contains(""))
                {
                    break;
                }
                else
                {
                }
            }
        }
        catch (OperationCanceledException)
        {
            MessageBox.Show("You have Successfuly Cancelled the event");
        }
        catch (Exception e)
        {

        }

        SL_Port.Dispose();
        SL_Port.Close();
        return listForFW;
    }

I have called cancel but the it does not work since the code is already executed awaiting response. 我已经调用了cancel,但是由于代码已经执行完毕并等待响应,所以它不起作用。

Here is my function call code 这是我的函数调用代码

 public async void startSending()
 {
   cts = new CancellationTokenSource();
   ReturnParams = await sendRecvCMDAsync(xport, commandSend, paramsList, cts.Token)
 }

Here is my cancel call code. 这是我的取消呼叫代码。

 public void btnCancelSend()
 {
    cts.Cancel();
 }

So how can I solve this issue? 那么我该如何解决这个问题呢? Cancellation isn't helping. 取消没有帮助。

The only way to cleanly kill (as in terminate) an operation is to run it in a separate process . 彻底终止(如终止)操作的唯一方法是在单独的进程中运行它。 Cancelling should be preferred. 取消应该是首选。

In your case, there is an alternative way to cancel (which is much easier): traditionally, Win32 asynchronous operations can be canceled by closing the handle they're operating on. 在您的情况下,还有另一种取消方法(这很容易):传统上,Win32异步操作可以通过关闭正在操作的句柄来取消。 This will cause all existing operations to complete (with an error). 这将导致所有现有操作完成(有错误)。

Note that this cancels all operations; 请注意,这将取消所有操作。 in particular, if you're reading and writing at the same time, both operations will error out if you close the handle. 特别是,如果您同时进行读写操作,则在关闭手柄时, 两种操作都会出错。

Start your own Thread . 启动您自己的Thread

Do message pumping on your own. 自行发送消息。

You can .Abort() it when hardware fails. 您可以在硬件出现故障时.Abort()它。 Your scenario is untypical for async/await. 您的方案对于异步/等待是不典型的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何取消异步任务? - How to cancel an asynchronous Task? 异步任务导致异常:System.ArgumentException:已添加具有相同键的项 - Asynchronous Task results in exception: System.ArgumentException: An item with the same key has already been added 如何取消使用 Rx 调用的异步方法 - How to cancel asynchronous method called using Rx 如何通知已从中调用方法的对象 - How to notify object from which a method has been called 如何证明返回IEnumerable的方法已被调用两次? - How to prove the method which returns IEnumerable has been called twice? 如何从已经异步的代码创建任务? - How to create a Task from already asynchronous code? 为什么在调用取消后线程继续运行? - Why threads continue to run after a cancel has been called? 是否有取消异步任务的正确方法? - Is there a proper way to cancel an asynchronous task? 如何通过Escape键正确取消并行异步IO Task? - How to properly cancel parallel asynchronous IO Task by Escape key? 如何判断 IRegistrationBuilder.EnableInterfaceInterceptors() 是否已被调用? - How can I tell if IRegistrationBuilder.EnableInterfaceInterceptors() has already been called?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM