سؤال

أنا أتصل ChannelServer.ListeningThread.Abort في الموضوع التالي ، ولكن يبدو أن لا شيء يحدث. أود أن أكون أكثر تحديدًا ، لكن لا يمكنني التفكير في أي شيء أكثر. يبدو أن هناك لا ThreadAbortException تم إلقاؤه ، ويجب إلقاء هذا الاستثناء بغض النظر عن مستمع الحظر (إنه يعمل بشكل مثالي على المواضيع التي تتطلع إلى حظرها).

تحرير مهم: مع ManualResetEvent.WaitOne بدلاً من AcceptSocket, ، كما اقترح Lyrik للاختبار ، فهو يعمل بشكل مثالي. كيف ذلك AcceptSocket يمنع ThreadAbortException?

حلقة الوصل: يبدو أن موضوع المنتدى يناقش نفس المشكلة ، على الرغم من أنني لا أستطيع معرفة أي شيء منه: http://www.tek-tips.com/viewthread.cfm؟qid=319436&page=413

ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate()
{
    Log.Inform("Waiting for clients on thread {0}.", Thread.CurrentThread.ManagedThreadId);

    while (true)
    {
        try
        {
            new Thread(new ParameterizedThreadStart(ChannelClientHandler.Initialize)).Start(ChannelServer.Listener.AcceptSocket());
        }
        catch (ThreadAbortException)
        {
            Log.Inform("Aborted client listening thread {0}.", Thread.CurrentThread.ManagedThreadId);
            break;
        }
    }
}));
ChannelServer.ListeningThread.Start();
هل كانت مفيدة؟

المحلول 2

هذا يعمل ، لكنه قذرة بشكل لا يصدق ويشعر بالخيوط. هل يمكن لأي شخص أن يوجهني إلى طريقة لإلقاء استثناء مفاده أن "قبول" لن يلتقط تلقائيًا؟

ChannelServer.ListeningThread = new Thread(new ThreadStart(delegate()
{
    Log.Inform("Waiting for clients on thread {0}.", Thread.CurrentThread.ManagedThreadId);

    while (true)
    {
        try
        {
            ChannelServer.ClientConnected.Reset();
            ChannelServer.Listener.BeginAcceptSocket(new AsyncCallback(ChannelClientHandler.EndAcceptSocket), ChannelServer.Listener);
            ChannelServer.ClientConnected.WaitOne();
        }
        catch (ThreadInterruptedException)
        {
            Log.Inform("Interrupted client listening thread {0}.", Thread.CurrentThread.ManagedThreadId);
            break;
        }
    }
}));
ChannelServer.ListeningThread.Start();

نصائح أخرى

لست متأكدًا من سبب حصولك على هذا الخطأ ، ولكن هنا مثال بسيط يعمل:

ManualResetEvent mrse = new ManualResetEvent(false);
Thread test = new Thread(() =>
    {
        while (true)
        {
            try
            {
                mrse.WaitOne();
            }
            catch (ThreadAbortException)
            {
                Console.WriteLine("No problem here...");
            }
        }
    });

test.IsBackground = true;
test.Start();

Thread.Sleep(1000);
test.Abort();
Console.ReadKey();

لذلك ينجح الأمر بالنسبة لي ... لقد افترضت أنك تجولت عبر مصحح الأخطاء ولم يتم ضرب نقطة الاستراحة الخاصة بك داخل بيان الصيد ، هل هذا صحيح؟

ملاحظة: من الممارسات السيئة الاتصال Abort, ، بدلاً من ذلك يجب عليك الاتصال Interrupt والتعامل مع ThreadInterruptedException... إنها أكثر أمانًا.

هنا بسيط AcceptSocket2 طريقة التمديد (آسف لعدم وجود خيال فيما يتعلق بالاسم ...). إنه يعمل تمامًا كما هو الأصلي AcceptSocket طريقة.

using System;
using System.Net.Sockets;
using System.Threading;

/// <summary>
/// Extensions to TcpListener
/// </summary>
public static class TcpListenerExtensions
{
    /// <summary>
    /// Accepts a pending connection request.
    /// </summary>
    /// <param name="tcpListener">The TCP listener.</param>
    /// <returns>
    /// A <see cref="T:System.Net.Sockets.Socket" /> used to send and receive data.
    /// </returns>
    /// <exception cref="T:System.InvalidOperationException">The listener has not been started with a call to <see cref="M:System.Net.Sockets.TcpListener.Start" />.</exception>
    /// <PermissionSet><IPermission class="System.Security.Permissions.EnvironmentPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /><IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /><IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="UnmanagedCode, ControlEvidence" /><IPermission class="System.Diagnostics.PerformanceCounterPermission, System, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Unrestricted="true" /></PermissionSet>
    public static Socket AcceptSocket2(this TcpListener tcpListener)
    {
        Socket socket = null;
        var clientConnected = new ManualResetEvent(false);
        clientConnected.Reset();
        tcpListener.BeginAcceptSocket(delegate(IAsyncResult asyncResult)
        {
            try
            {
                socket = tcpListener.EndAcceptSocket(asyncResult);
            }
            catch (ObjectDisposedException)
            { }
            clientConnected.Set();
        }, null);
        clientConnected.WaitOne();
        return socket;
    }
}
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top