草庐IT

c# - 异步 TCP 操作期间的 AccessViolation

coder 2023-09-19 原文

在各种异步 TCP 操作期间,我不断收到未处理的 AccessViolationException。 该异常仅出现在内置函数的反汇编窗口中 System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)。异常的堆栈跟踪仅包含此函数。流水线是:cmp dword ptr [ecx], ecx.
最烦人的是异常不规则地到达(程序可以在它之前执行30分钟或6小时或15秒)。

这里是完整的异常描述:

System.AccessViolationException unhandled
  HResult=-2147467261
  Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Source=mscorlib
StackTrace:
   in System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
InnerException: 

代码: 在尝试以任何方式访问 TCP 套接字异步期间,我遇到了这个异常。我不使用外部非托管代码。这是我最后一次尝试异步连接到远程地址组。

class Program
{
    static void Main(string[] args)
    {
        PollerCore p = new PollerCore();

        p.Start();
        Console.ReadLine();
    }
}
public class PollerCore
{
    string[] ip = new string[255];
    public void Start()
    {
        for (int i = 1; i < 255; i++)
        {
            ip[i] = String.Format("192.168.100.{0}", i);
        }
        new Thread(WorkerThread).Start();

    }

    async void WorkerThread()
    {
        while (true)
        {
            Console.WriteLine("In wt... ");
            DateTime dt = DateTime.Now;

            List<Task<string>> tasks = new List<Task<string>>();

            foreach (string addr in ip)
            {
                if (String.IsNullOrEmpty(addr)) continue;
                tasks.Add(ConnectToDevice(addr));
            }
            string[] res = await Task.WhenAll(tasks.ToArray());

            foreach (string s in res)
            {
                if (s != null) Console.WriteLine("Connecting to {0}... DONE", s);
            }
            Thread.Sleep(100);
        }
    }

    async Task<string> ConnectToDevice(string ip)
    {
        using (TcpClient c = new TcpClient())
        {
            try
            {
                await c.ConnectAsync(ip, 5100);
                return ip;
            }
            catch
            {
                return null;
            }
        }
    }

}

更新: 根据 Noseratio 建议修改了代码中引发的相同异常。 Thread.Start 已替换为 Task.Run。在

catch
{
    return null;
}

我只收到代码为 10060(超时)的 SocketExceptions...

最佳答案

我认为问题可能出在这里:

new Thread(WorkerThread).Start();

// ...

async void WorkerThread() 
{
    // ...
}

尝试将其更改为:

var task = Task.Run(() => WorkerThreadAsync());
task.Wait(); // for debugging

// ...

async Task WorkerThreadAsync() 
{
    // ...
}

或者,根本不使用单独的线程:

var task = WorkerThreadAsync();
task.Wait(); // for debugging

无论如何,您在 WorkerThread 中使用异步 API,在第一个 await 之后很可能会切换到不同的池线程。

还有一些事情:

  • 不要这样做:catch { return null } 。转储实际的异常信息。
  • 您将在 ConnectAsync 任务完成后立即处理 TcpClient,即一旦客户端连接到服务器:使用 (TcpClient c =新的 TcpClient()) { ... } 。之后你真的不再使用 TcpClient 对象了吗?

关于c# - 异步 TCP 操作期间的 AccessViolation,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22188862/

有关c# - 异步 TCP 操作期间的 AccessViolation的更多相关文章

  1. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  2. c# - 如何在 ruby​​ 中调用 C# dll? - 2

    如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

  3. C# 到 Ruby sha1 base64 编码 - 2

    我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

  4. 基于C#实现简易绘图工具【100010177】 - 2

    C#实现简易绘图工具一.引言实验目的:通过制作窗体应用程序(C#画图软件),熟悉基本的窗体设计过程以及控件设计,事件处理等,熟悉使用C#的winform窗体进行绘图的基本步骤,对于面向对象编程有更加深刻的体会.Tutorial任务设计一个具有基本功能的画图软件**·包括简单的新建文件,保存,重新绘图等功能**·实现一些基本图形的绘制,包括铅笔和基本形状等,学习橡皮工具的创建**·设计一个合理舒适的UI界面**注明:你可能需要先了解一些关于winform窗体应用程序绘图的基本知识,以及关于GDI+类和结构的知识二.实验环境Windows系统下的visualstudio2017C#窗体应用程序三.

  5. ruby - 如何使用 Selenium Webdriver 根据 div 的内容执行操作? - 2

    我有一个使用SeleniumWebdriver和Nokogiri的Ruby应用程序。我想选择一个类,然后对于那个类对应的每个div,我想根据div的内容执行一个Action。例如,我正在解析以下页面:https://www.google.com/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=puppies这是一个搜索结果页面,我正在寻找描述中包含“Adoption”一词的第一个结果。因此机器人应该寻找带有className:"result"的div,对于每个检查它的.descriptiondiv是否包含单词“adoption

  6. ruby-on-rails - 如何处理 Grape 中特定操作的过滤器之前? - 2

    我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?

  7. ruby-on-rails - 在 Ruby on Rails 中发送响应之前如何等待多个异步操作完成? - 2

    在我做的一些网络开发中,我有多个操作开始,比如对外部API的GET请求,我希望它们同时开始,因为一个不依赖另一个的结果。我希望事情能够在后台运行。我找到了concurrent-rubylibrary这似乎运作良好。通过将其混合到您创建的类中,该类的方法具有在后台线程上运行的异步版本。这导致我编写如下代码,其中FirstAsyncWorker和SecondAsyncWorker是我编写的类,我在其中混合了Concurrent::Async模块,并编写了一个名为“work”的方法来发送HTTP请求:defindexop1_result=FirstAsyncWorker.new.async.

  8. ruby - 在 Ruby 中是否有一种惯用的方法来操作 2 个数组? - 2

    a=[3,4,7,8,3]b=[5,3,6,8,3]假设数组长度相同,是否有办法使用each或其他一些惯用方法从两个数组的每个元素中获取结果?不使用计数器?例如获取每个元素的乘积:[15,12,42,64,9](0..a.count-1).eachdo|i|太丑了...ruby1.9.3 最佳答案 使用Array.zip怎么样?:>>a=[3,4,7,8,3]=>[3,4,7,8,3]>>b=[5,3,6,8,3]=>[5,3,6,8,3]>>c=[]=>[]>>a.zip(b)do|i,j|c[[3,5],[4,3],[7,6],

  9. ruby-on-rails - 如何让 Rails View 返回其关联的操作名称? - 2

    我有一个非常简单的Controller来管理我的Rails应用程序中的静态页面:classPagesController我怎样才能让View模板返回它自己的名字,这样我就可以做这样的事情:#pricing.html.erb#-->"Pricing"感谢您的帮助。 最佳答案 4.3RoutingParametersTheparamshashwillalwayscontainthe:controllerand:actionkeys,butyoushouldusethemethodscontroller_nameandaction_nam

  10. 多种方法期间的 Ruby 救援异常 - 2

    我构建了一个简单的银行应用程序,它能够执行通常的操作;充值、提现等我的Controller方法执行这些操作并拯救由帐户或其他实体引发的异常。以下是Controller代码中使用的一些方法:defopen(type,with:)account=createtype,(holders.findwith)addaccountinit_yearly_interest_foraccountboundary.renderAccountSuccessMessage.new(account)rescueItemExistError=>messageboundary.rendermessageendde

随机推荐