Mijn vraag
...
In een project (console .net 4.52) waarin SignalR prima werkt moet ik wat toevoegen.
Ik heb een een long running Task<T> die ik als parameter een IProgress<T> meegeef.
Dit zou volgens de documentatie gewoon moeten kunnen.
Ik krijg alleen de meest wazige errors en het wil gewoon niet werken.
In de console applicatie knalt ie er zonder melding uit. Het proces wordt gewoon afgesloten op het moment dat ik de hub invoke. Er valt kennelijk niets te catchen.
Wat ik al gevonden of geprobeerd heb
...
Om het probleem te isoleren heb ik het na proberen te bootsen in een los project.
Ik heb een server hub gemaakt in een console applicatie met OWIN
Een client in een console applicatie
Een client in een Winforms applicatie
In de console client knalt ie eruit als ik een await gebruik op de hub.invoke
Doe ik echter een .Wait() of een .Result() op een functie uit de hub (eentje zonder Progress<T>) dan werkt het wel.
In de Winforms applicatie heb ik dit probleem niet. Dit zal waarschijnlijk iets te maken hebben met de synchronizationcontext vermoed ik.
Maar dit is niet het ergste probleem, wilde het alleen even opnoemen voor als iemand daar een makkelijk antwoord op heeft.
In mijn hub heb ik de volgende testmethode:
Die roep ik in mijn client als volgt aan:
Die knalt er vrijwel direct uit met:
Alsof ie geen parameter verwacht.
Verander ik in de hub de IProgress parameter met een int (waar ik vervolgens niets mee doe) dan krijg ik gewoon netjes "Job complete" terug na even gewacht te hebben. Het is dus echt een probleem van de parameter.
Puur om te testen heb ik de functie eens aangepast om na de IProgress ook nog een dummy int mee te geven. Ik was benieuwd waar ie dan mee zou komen.
Dus
En in de client
Dan klapt ie eruit met
Dat zegt me al een stuk meer. Hij ziet ineens de parameters (wel heel vreemd natuurlijk) en de melding is volgens mij van de deserializer die een instance probeert te maken van een interface (wat natuurlijk niet gaat)
Maar goed, voordat ik hier allemaal trucs op ga verzinnen krijg ik het vermoeden dat ik ergens gewoon iets niet goed aan het doen ben.
Zijn er hier mensen die met IProgress werken in SignalR en met een .Net client?
Ik heb voor hulpvaardigen die zelf een kijkje willen nemen wel een testproject.
Liever heb ik gewoon een duw of stomp in de goede richting
...
In een project (console .net 4.52) waarin SignalR prima werkt moet ik wat toevoegen.
Ik heb een een long running Task<T> die ik als parameter een IProgress<T> meegeef.
Dit zou volgens de documentatie gewoon moeten kunnen.
Ik krijg alleen de meest wazige errors en het wil gewoon niet werken.
In de console applicatie knalt ie er zonder melding uit. Het proces wordt gewoon afgesloten op het moment dat ik de hub invoke. Er valt kennelijk niets te catchen.
Wat ik al gevonden of geprobeerd heb
...
Om het probleem te isoleren heb ik het na proberen te bootsen in een los project.
Ik heb een server hub gemaakt in een console applicatie met OWIN
Een client in een console applicatie
Een client in een Winforms applicatie
In de console client knalt ie eruit als ik een await gebruik op de hub.invoke
Doe ik echter een .Wait() of een .Result() op een functie uit de hub (eentje zonder Progress<T>) dan werkt het wel.
In de Winforms applicatie heb ik dit probleem niet. Dit zal waarschijnlijk iets te maken hebben met de synchronizationcontext vermoed ik.
Maar dit is niet het ergste probleem, wilde het alleen even opnoemen voor als iemand daar een makkelijk antwoord op heeft.
In mijn hub heb ik de volgende testmethode:
C#:
1
2
3
4
5
6
7
8
9
10
| public async Task<string> DoLongRunningThing(IProgress<int> progress) { for (int i = 0; i <= 100; i += 5) { await Task.Delay(200); progress.Report(i); } return "Job complete!"; } |
Die roep ik in mijn client als volgt aan:
C#:
1
2
| IProgress<int> progress = new Progress<int>(value=>Console.WriteLine(value)); var result = await HubProxy.Invoke<string>("DoLongRunningThing", progress); |
Die knalt er vrijwel direct uit met:
code:
1
2
| System.InvalidOperationException: ''DoLongRunningThing' method could not be resolved. Potential candidates are: DoLongRunningThing():Task`1' |
Alsof ie geen parameter verwacht.
Verander ik in de hub de IProgress parameter met een int (waar ik vervolgens niets mee doe) dan krijg ik gewoon netjes "Job complete" terug na even gewacht te hebben. Het is dus echt een probleem van de parameter.
Puur om te testen heb ik de functie eens aangepast om na de IProgress ook nog een dummy int mee te geven. Ik was benieuwd waar ie dan mee zou komen.
Dus
C#:
1
2
3
4
5
6
7
8
9
10
| public async Task<string> DoLongRunningThing(IProgress<int> progress,int dummy) { for (int i = 0; i <= 100; i += 5) { await Task.Delay(200); progress.Report(i); } return "Job complete!"; } |
En in de client
C#:
1
2
| IProgress<int> progress = new Progress<int>(value=>Console.WriteLine(value)); var result = await HubProxy.Invoke<string>("DoLongRunningThing", progress,1234); |
Dan klapt ie eruit met
code:
1
2
3
| System.InvalidOperationException HResult=0x80131509 Message=Could not create an instance of type System.IProgress`1[System.Int32]. Type is an interface or abstract class and cannot be instantiated. Path '', line 1, position 2. |
Dat zegt me al een stuk meer. Hij ziet ineens de parameters (wel heel vreemd natuurlijk) en de melding is volgens mij van de deserializer die een instance probeert te maken van een interface (wat natuurlijk niet gaat)
Maar goed, voordat ik hier allemaal trucs op ga verzinnen krijg ik het vermoeden dat ik ergens gewoon iets niet goed aan het doen ben.
Zijn er hier mensen die met IProgress werken in SignalR en met een .Net client?
Ik heb voor hulpvaardigen die zelf een kijkje willen nemen wel een testproject.
Liever heb ik gewoon een duw of stomp in de goede richting
Lekker op de bank