gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 02:52:03 25 4
gpt4 key购买 nike

在各种异步 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com