| 

.NET C# Java Javascript Exception

2
Hallo geehrte Community-Mitglieder,

meine Frage ist recht speziell, aber vielleicht verfolge ich auch einen falschen Ansatz.
Daher möchte ich zuerst mein Problem schildern.

Ich arbeite an einem großen Projekt mit.
Dabei werden viele WCF-Services verwendet.
Die WCF-Services befinden sich (je nach Zusammenhang) in eigenen VS-Projekten.
Die Contracts/Verträge (Interfaces) befinden sich ebenfalls in eigenen Bibliotheken.
Die Bibliothek mit den Interfaces wird Server-seitig zur Implementierung im Service verwendet und Client-seitig zum Aufrufen des Services.

Wir haben also eine Struktur wie diese:

  • Shared (Bibliotheken zur Verwendun in Server und Client)
  • Client (Client-Bibliotheken, Server kennt diese nicht)
  • Server (Server-Bibliotheken, Client kennt diese nicht)


Jetzt kommen wir dem Problem schon näher.
Da die Interfaces nicht über eine WSDL generiert, sondern stattdessen die gleichen Interfaces (gleiche Bibliothek) für den Server auch im Client angewendet werden, fällt die Möglichkeit weg, sich über Visual Studio TAP-Methoden generieren zu lassen.

Wir haben also einen Service wie diesen (Beispiel):
public interface IDataService
{
string GetData(int number);
}


Ziel ist es, für diesen Aufruf als Task (TAP) durchzuführen.

Eine Möglichkeit, die naheliegend scheint, wäre diese:
public class DataClient
{
IDataService service;

public Task<string> GetDataAsync(int number)
{
return Task.Run(() => service.GetData(number));
}
}


Als ich mich mit dem Thema "async/await" befasst hatte, traf ich immer wieder auf Punkte, die darauf hinwiesen, dass man so nicht bei IO-Vorgängen vorgehen sollte, da man den ThreadPool unnötig mit "nichts-tuenden" Threads belastet.

Als Alternative habe ich gelesen, dass man auch sein Interface wie folgt anpassen kann:
public interface IDataService
{
string GetData(int number);
Task<string> GetDataAsync(int number);
}


Aber dann müsste ich (da dieselbe Bibliothek mit dem Interface Client- und Server-seitig verwendet wird) beide Methoden im Service implementieren.
Das kann aber nicht die richtige Vorgehensweise sein.

Denn wenn man über die Visual Studio integrierte Funktion ein Interface generiert, welches diese TAP-Methoden aufweist, dann kann WCF mit dieser Differenz (Unterschied zwischen Client-seitigem Interface und Server-seitigem Interface) umgehen.

Zusammengefasst: es ist also möglich eine TAP-Methode über den Client aufzurufen ohne sie im Server implementiert oder gekennzeichnet zu haben.

Aber wie macht man das?

Ich hatte bislang schon eine Idee verfolgt:
public class DataClient
{
IDataService service;

public Task<string> GetDataAsync(int number)
{
return InvokeAsync(x => x.GetData(number));
}

public async Task<TResult> InvokeAsync<TResult>(Expression<Func<TServiceInterface, TResult>> executionExpression)
{
// ...
}
}


Die Methode InvokeAsync wertet dabei den Lambda-Ausdruck aus, sodass ich am Ende folgendes machen kann:
public Task<TResult> InvokeAsync<TResult>(string methodName, object[] args)
{
return Task.Factory.
FromAsync(
(callback, state) => this.BeginInvoke(methodName, args, callback, state),
(result) => { return (TResult)this.EndInvoke(methodName, args, result); },
this
);
}


Dabei bin ich auf das Problem gestoßen, dass die generierte ContractDescription zwar eine OperationDescription mit "GetData" enthält, aber dort der Verweis auf eine TAP-Methode "im Interface" fehlt.

Jetzt überlege ich, ob man eine OperationDescription zur Laufzeit generieren kann.
Aber die OperationDescription benötigt einen Verweis auf die Methode (Eigenschaft: TaskMethod - Link zur MSDN)

Falls bei diesem recht komplexen Problem jemand einen Tipp hat, dann würde ich mich freuen.

Vielen Dank und Gruß,
Marcus.D
News:
20.05.2015
Marcus.D 86 1 4
TOP TECHNOLOGIES CONSULTING GmbH