Diskuze: task-based Windows Communication Foundation

C# .NET .NET (C# a Visual Basic) task-based Windows Communication Foundation American English version English version

Avatar
Gramli
Redaktor
Avatar
Gramli:

Zdravím,
mám dotaz ohledně stahování souborů ze služby, kterou jsem vytvořil.
Chtěl bych aby posílání souborů ze služby probíhalo tak, aby to službu "Nezasekalo" -> aby mohl stahovat ze služby v daném okamžiku i někdo jiný.

v Interface je metoda definována takto:

    [OperationContract]
    [FaultContract(typeof(CustomException))]
    Task<RemoteFileInfo> DownloadFile(DownloadRequest request);

public class RemoteFileInfo : IDisposable
{
    [MessageHeader(MustUnderstand = true)]
    public string FileName;

    [MessageHeader(MustUnderstand = true)]
    public long Length;

    [MessageHeader(MustUnderstand=true)]
    public Login login;

    [MessageBodyMember(Order = 1)]
    public System.IO.Stream FileByteStream;

    public void Dispose()
    {
        if (FileByteStream != null)
        {
            FileByteStream.Close();
            FileByteStream = null;
        }
    }
}

a kód metody DownloadFile vypadá takto:

public async Task<RemoteFileInfo> DownloadFile(DownloadRequest request)
        {
            var task = Task.Run(() =>
                {
                    if (!CheckUser(request.login))
                    {
                        CustomException my = SetException("Login error", "Invalid UserName or Password", "", "");
                        throw new FaultException<CustomException>(my);
                    }

                    RemoteFileInfo result = new RemoteFileInfo();
                    try
                    {
                        string filePath = request.FileAdress;
                        System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

                        // check if exists
                        if (!fileInfo.Exists)
                            throw new FileNotFoundException("File not found", request.FileName);

                        // open stream
                        FileStream stream = new System.IO.FileStream(request.FileAdress, FileMode.Open, System.IO.FileAccess.Read);
                        // return result
                        result.FileName = request.FileName;
                        result.Length = fileInfo.Length;
                        result.FileByteStream = stream;

                    }
                    catch (Exception ex)
                    {
                        CustomException my = SetException("Error function: DownloadFile", ex.Message, ex.InnerException.Message, ex.StackTrace);
                        throw new FaultException<CustomException>(my);
                    }
                    return result;
                });
            return await task.ConfigureAwait(false);
        }

Ale ikdyž to mám napsáno takto, tak při stahování je služba zasekaná -> nemůže stahovat další klient. Máte s tímto někdo zkušenosti? Budu rád, za každou radu :)

Dodatek ke službe: je to self-hosted služba a připojuji se k ní pomocí klienta s ChannelFactory. Klient ani hostovací aplikace nemají nastavení v configuračním souboru, ale přímo v kódu.

Odpovědět 4.7.2014 9:10
Kdo to říká ten to je...
Avatar
Gramli
Redaktor
Avatar
Gramli:

Tak jsem problém vyřešil, postnu ho, kdyby někdo řešil něco podobného:

Interface:

[OperationContract]
[FaultContract(typeof(CustomException))]
RemoteFileInfo DownloadFile(DownloadRequest request);

[MessageContract]
public class RemoteFileInfo : IDisposable
{
[MessageHeader(MustUnderstand = true)]
public string FileName;

[MessageHeader(MustUnderstand = true)]
public long Length;

[MessageHeader(MustUnderstand=true)]
public Login login;

[MessageBodyMember(Order = 1)]
public System.IO.Stream FileByteStream;

public void Dispose()
{
    if (FileByteStream != null)
    {
        FileByteStream.Close();
        FileByteStream = null;
    }
}
}

Metoda DownloadFile:

public RemoteFileInfo DownloadFile(DownloadRequest request)
        {
                    if (!CheckUser(request.login))
                    {
                        CustomException my = SetException("Login error", "Invalid UserName or Password", "", "");
                        throw new FaultException<CustomException>(my);
                    }

                    RemoteFileInfo result = new RemoteFileInfo();
                    try
                    {
                        string filePath = request.FileAdress;
                        System.IO.FileInfo fileInfo = new System.IO.FileInfo(filePath);

                        // check if exists
                        if (!fileInfo.Exists)
                            throw new FileNotFoundException("File not found", request.FileName);

                        // open stream
                        FileStream stream = new System.IO.FileStream(request.FileAdress, FileMode.Open, System.IO.FileAccess.Read);
                        // return result
                        result.FileName = request.FileName;
                        result.Length = fileInfo.Length;
                        result.FileByteStream = stream;

                    }
                    catch (Exception ex)
                    {
                        CustomException my = SetException("Error function: DownloadFile", ex.Message, ex.InnerException.Message, ex.StackTrace);
                        throw new FaultException<CustomException>(my);
                    }
                    return result;
        }

nastaveni behaviour:

[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall,ConcurrencyMode = ConcurrencyMode.Multiple)]
    public class Streaming : ServiceInterface

ServiceHost:

//Create a URI to serve as the base address
                Uri httpUrl = new Uri("http://localhost:8092/PSIService");
                //Create ServiceHost
                _host = new ServiceHost(typeof(Service.Streaming), httpUrl);

                //Set binding
                BasicHttpBinding hostBinging = SetBinding();

                ServiceMetadataBehavior smb = _host.Description.Behaviors.Find<ServiceMetadataBehavior>();
                if (smb == null)
                {
                    smb = new ServiceMetadataBehavior();
                    smb.HttpGetEnabled = true;
                    _host.Description.Behaviors.Add(smb);
                }

                //Add a service endpoint
                _host.AddServiceEndpoint(typeof(Service.ServiceInterface), hostBinging, "");
                //Enable metadata exchange
                // checking and publishing meta data
                //Start the Service
                _host.Open();

Dále pokud hostujete aplikaci v WinForms musíte serviceHost vytvořit v jiném vlákně.

Nahoru Odpovědět 5.7.2014 11:34
Kdo to říká ten to je...
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 2 zpráv z 2.