Simile al suggerimento di @ David di inserire i dati in una tabella "progress", ma senza la necessità di pasticciare con problemi di pulizia o di concorrenza / separazione dei processi:
- Creane uno nuovo
Guid
nel codice dell'app e passalo come parametro alla Stored Procedure. Conservare questo Guid in una variabile in quanto verrà utilizzato più volte.
- Nella Stored procedure, crea una tabella temporanea globale usando quella guida come parte del nome della tabella, qualcosa del genere
CREATE TABLE ##MyProcess_{GuidFromApp};
. La tabella può avere qualunque colonna di qualunque tipo di dato sia necessario.
Ogni volta che si dispone dei dati, inserirli nella tabella delle temp globali.
Nel codice dell'app, iniziare a provare a leggere i dati, ma racchiuderlo SELECT
in in IF EXISTS
modo che non fallisca se la tabella non è stata ancora creata:
IF (OBJECT_ID('tempdb..[##MyProcess_{0}]')
IS NOT NULL)
BEGIN
SELECT * FROM [##MyProcess_{0}];
END;
Con String.Format()
, è possibile sostituire {0}
con il valore nella variabile Guid. Verifica se Reader.HasRows
, e se vero, leggi i risultati, altrimenti chiama Thread.Sleep()
o qualsiasi altra cosa per eseguire nuovamente il polling.
Benefici:
- Questa tabella è isolata da altri processi poiché solo il codice dell'app conosce il valore Guid specifico, quindi non è necessario preoccuparsi di altri processi. Un altro processo avrà una propria tabella temporanea globale privata.
- Perché è una tabella, tutto è fortemente tipizzato.
- Poiché si tratta di una tabella temporanea, al termine della sessione che esegue la Stored Procedure, la tabella verrà ripulita automaticamente.
- Perché è una tabella temporanea globale :
- è accessibile da altre sessioni, proprio come una tabella permanente
- sopravviverà alla fine del sottoprocesso in cui è stato creato (ovvero il
EXEC
/ sp_executesql
call)
Ho provato questo e funziona come previsto. Puoi provarlo tu stesso con il seguente codice di esempio.
In una scheda della query, eseguire quanto segue, quindi evidenziare le 3 righe nel commento a blocchi ed eseguirlo:
CREATE
--ALTER
PROCEDURE #GetSomeInfoBackQuickly
(
@MessageTableName NVARCHAR(50) -- might not always be a GUID
)
AS
SET NOCOUNT ON;
DECLARE @SQL NVARCHAR(MAX) = N'CREATE TABLE [##MyProcess_' + @MessageTableName
+ N'] (Message1 NVARCHAR(50), Message2 NVARCHAR(50), SomeNumber INT);';
-- Do some calculations
EXEC (@SQL);
SET @SQL = N'INSERT INTO [##MyProcess_' + @MessageTableName
+ N'] (Message1, Message2, SomeNumber) VALUES (@Msg1, @Msg2, @SomeNum);';
DECLARE @SomeNumber INT = CRYPT_GEN_RANDOM(2);
EXEC sp_executesql
@SQL,
N'@Msg1 NVARCHAR(50), @Msg2 NVARCHAR(50), @SomeNum INT',
@Msg1 = N'wow',
@Msg2 = N'yadda yadda yadda',
@SomeNum = @SomeNumber;
WAITFOR DELAY '00:00:10.000';
SET @SomeNumber = CRYPT_GEN_RANDOM(3);
EXEC sp_executesql
@SQL,
N'@Msg1 NVARCHAR(50), @Msg2 NVARCHAR(50), @SomeNum INT',
@Msg1 = N'wow',
@Msg2 = N'yadda yadda yadda',
@SomeNum = @SomeNumber;
WAITFOR DELAY '00:00:10.000';
GO
/*
DECLARE @TempTableID NVARCHAR(50) = NEWID();
RAISERROR('%s', 10, 1, @TempTableID) WITH NOWAIT;
EXEC #GetSomeInfoBackQuickly @TempTableID;
*/
Vai alla scheda "Messaggi" e copia il GUID che è stato stampato. Quindi, apri un'altra scheda della query ed esegui quanto segue, posizionando il GUID che hai copiato dalla scheda Messaggi dell'altra sessione nell'inizializzazione della variabile alla riga 1:
DECLARE @TempTableID NVARCHAR(50) = N'GUID-from-other-session';
EXEC (N'SELECT * FROM [##MyProcess_' + @TempTableID + N']');
Continua a colpire F5. Dovresti vedere 1 voce per i primi 10 secondi, quindi 2 voci per i successivi 10 secondi.