Attività Disegno della libreria della console parallela - Come si blocca un thread in un contesto specifico?

3

Attualmente sto sviluppando un'applicazione che si basa su più socket che ascoltano i messaggi di chat. Quando i messaggi arrivano, vengono trasmessi a un bot associato ai loro canali. A causa del numero elevato di canali a cui è associato questo bot, è altamente inefficiente creare un thread per ogni bot.

Idealmente, quello che sto cercando è quello di sparare un compito, che verrà eseguito all'interno di un pool di attività per elaborare i messaggi per ogni bot. Mi piacerebbe avere un pool di thread di 30-100 thread in esecuzione che elaborano i messaggi contemporaneamente, ma solo 1 thread collegato a un bot specifico (o socket). Ho letto un po 'della Libreria parallela attività, ma sono confuso su come bloccare in un contesto specifico.

Tutto inizia qui:

IrcConnection.BeginReceive(state.Buffer, 0, state.Buffer.Length, SocketFlags.None, RecieveComplete, state);

//When a message comes in, it calls RecieveComplete, which invokes an event handler:

UserMessageRecieved?.Invoke(this, new UserMessageEventArgs(userMessage));

//And the event handler:
public async void bot_UserMessageRecieved(object sender, UserMessageEventArgs e)

Al momento, è possibile eseguire più thread contemporaneamente per accedere a un singolo contesto bot. Quale sarebbe una buona soluzione per evitare che ciò accada? La TPL è la strada giusta per questo progetto?

    
posta FrankerZ 26.02.2017 - 18:48
fonte

1 risposta

1

In base alla tua domanda, hai bisogno di un agente per elaborare più processi per inviare e ricevere messaggi in parallelo, ma l'elaborazione di questi messaggi deve avere un comportamento asincrono, perché hai a che fare con I / O. La maggior parte delle operazioni di I / O (incluso il socket TCP) di solito blocca, quindi avere implementato async è l'opzione migliore.

Ma combinare il parallelismo con l'operazione asincrona non è un compito facile se si utilizza .NET EAP (pattern asincrono degli eventi), che è stato mostrato nella domanda. Conosco il modello EAP .NET, perché nel metodo si utilizza lo schema Beginxxx e Endxxx. Ciò a sua volta rende più difficile l'uso asincrono. È difficile, perché tutte le operazioni asincrone e di attesa devono incapsulare la coppia di metodi Beginxxx e Receivexx (o Endxxx).

Dovresti essere consapevole che il modello EAP è ora considerato modello legacy async in .NET 4.5 e versioni successive, basta controllare i collegamenti MSDN Library di seguito.

Per la programmazione parallela, è disponibile nel modello NET TPL (Task Parallel Library). Questo TPL .NET descrive solo la programmazione parallela. Se stai per utilizzare async-await, devi controllare il modello .NET TAP (Task Asynchrony Pattern), e questo è il motivo per cui .NET TAP non è esattamente lo stesso di .NET TPL.

Ti suggerisco di utilizzare l'API di socket .NET 4.5 (e successiva) esistente in System.Net.Sockets (ad esempio, guarda i metodi di TcpListener che hanno il suffisso Async), e poi combina ogni esecuzione di il metodo asincrono in un'esecuzione parallela.

In secondo luogo, non utilizzare un singolo contesto per il tuo bot. Avere una programmazione parallela significa essere consapevoli del fatto che si avranno più contesti di esecuzione eseguiti separatamente. Avere un solo contesto aumenterà le difficoltà, perché dovresti gestire gli stati per conversazioni di messaggi diversi. Ma il tuo chilometraggio può variare, però.

Ultimi suggerimenti: non esiste un singolo punto elenco per qualsiasi modello di concorrenza.

Per ulteriori informazioni su .NET EAP, visitare: link

Per ulteriori informazioni su .NET TAP, visita: link

Per ulteriori informazioni su .NET TPL, visitare: link

UPDATE 1 (basato sui commenti) :

Utilità di pianificazione? Sì, per il pianificatore di attività / contesto di sincronizzazione in TPL, visitare l'esempio di TaskScheduler in .NET TPL: link

Ma fai attenzione quando utilizzi questo corso, assicurati di aver aggiunto il supporto di CancellationToken in tutte le attività di creazione dell'attività, altrimenti otterrai comportamenti imprevedibili se il tuo processo è bloccato / a tempo scaduto.

Se si desidera avere maggiore controllo su come si desidera la sequenza e la granularità del numero massimo di operazioni parallele, è possibile combinare la programmazione parallela in .NET TPL utilizzando l'esecuzione parallela personalizzata. Ad esempio, puoi eseguire Parallel.Per con ParallelLoopState aggiuntivo e ParallelOptions .

Ad esempio: consulta la documentazione di Parallel.For con ParallelOptions di utilizzo a: link

    
risposta data 26.02.2017 - 19:14
fonte

Leggi altre domande sui tag