Reputation: 37
I'm continuously getting unhandled AccessViolationException
during various async TCP operations.
The exception arises only in Disassembly window in built-in function
System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32 errorCode, UInt32 numBytes, NativeOverlapped* pOVERLAP)
. Stack trace of the exception contains only this function. Assembly line is: cmp dword ptr [ecx], ecx
.
The most annoying thing is that exception arrives irregularly (program can execute 30 minutes or 6 hours or 15 seconds before it).
Here is full exception description:
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:
The code: I've got this exception during any tries to access TCP socket async in any way. I don't use external unmanaged code. Here is my last try to connect to group of remote address asynchronously.
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;
}
}
}
}
Update: The same exception raised in code reworked according Noseratio suggestions. Thread.Start was replaced with Task.Run. In
catch
{
return null;
}
I was receiving only SocketExceptions with code 10060 (Timeout)...
Upvotes: 1
Views: 1411
Reputation: 61736
I think the problem might be here:
new Thread(WorkerThread).Start();
// ...
async void WorkerThread()
{
// ...
}
Try changing it to this:
var task = Task.Run(() => WorkerThreadAsync());
task.Wait(); // for debugging
// ...
async Task WorkerThreadAsync()
{
// ...
}
Alternatively, don't use a separate thread at all:
var task = WorkerThreadAsync();
task.Wait(); // for debugging
You use async APIs inside WorkerThread
anyway, a switch to a different pool thread will most likely occur after the first await
.
A few more things:
catch { return null }
. Dump the actual exception information.TcpClient
as soon as the ConnectAsync
task has completed, i.e. once the client has connected to the server: using (TcpClient c = new TcpClient()) { ... }
. Are you really no longer using the TcpClient
object after that?Upvotes: 1