WCF Stream => FileStream Async
От: mDmitriy Россия  
Дата: 06.03.21 19:30
Оценка:
Всем привет!

Есть примерно такой рабочий код:
interface IService
{
     [OperationContract]
     bool UploadStore(Stream stream);
}

[ServiceBehavior]
class Service : IService
{
    [OperationBehavior(AutoDisposeParameters = true)]
    public bool UploadStore(Stream stream)
    {
        using(var fileStream = new FileStream("myFille.txt", FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
        {
            stream.CopyTo(fileStream);
            fileStream.Position = 0;
            fileStream.Flush(true);
        }
        return true;
    }
}

Просто приходит поток от клиента и пишется в файл
Надо чтобы он записывался в файл асинхнонно
Т.е., чтобы клиент синхронно получал ответ, когда стрим пришел на сервер, а дальше стрим уже неспешно в другом потоке куда-то записывался
Я знаю, что можно это написать через Task.Run(()=> { ... })
А как правильно? Чтобы через асинхронные методы FileStream

Спасибо
Re: WCF Stream => FileStream Async
От: takTak  
Дата: 06.03.21 20:11
Оценка: 70 (1)
сигнатуру надо изменить на

public Task<bool> UploadStore(Stream stream)


а потом

await outputFile.WriteAsync(content);


или так:

using (var stream = new FileStream(
    "output4.txt", FileMode.Create, FileAccess.Write, FileShare.Write, 4096, useAsync:true))
{
    var bytes = Encoding.UTF8.GetBytes(content);
    await stream.WriteAsync(bytes, 0, bytes.Length);
}
Re[2]: WCF Stream => FileStream Async
От: Sharov Россия  
Дата: 31.03.21 18:32
Оценка:
Здравствуйте, takTak, Вы писали:

T>сигнатуру надо изменить на


T>
T>public Task<bool> UploadStore(Stream stream)
T>


T>а потом


T>
T>await outputFile.WriteAsync(content);
T>


T>или так:


T>
T>using (var stream = new FileStream(
T>    "output4.txt", FileMode.Create, FileAccess.Write, FileShare.Write, 4096, useAsync:true))
T>{
T>    var bytes = Encoding.UTF8.GetBytes(content);
T>    await stream.WriteAsync(bytes, 0, bytes.Length);
T>}
T>



А клиент то что увидит? Он true также получит не раньше, когда копирование закончится.
Кодом людям нужно помогать!
Re: WCF Stream => FileStream Async
От: varenikAA  
Дата: 01.04.21 05:49
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>Я знаю, что можно это написать через Task.Run(()=> { ... })

D>А как правильно? Чтобы через асинхронные методы FileStream
Почему нет? Только надо протестировать, чтобы стрим не уничтожился после завершения основного метода.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[2]: WCF Stream => FileStream Async
От: takTak  
Дата: 01.04.21 06:12
Оценка:
D>>Я знаю, что можно это написать через Task.Run(()=> { ... })
D>>А как правильно? Чтобы через асинхронные методы FileStream
AA>Почему нет? Только надо протестировать, чтобы стрим не уничтожился после завершения основного метода.

https://exceptionnotfound.net/two-ways-to-do-async-await-in-asp-net-wrong-and-how-to-fix-them/
https://devblogs.microsoft.com/pfxteam/should-i-expose-asynchronous-wrappers-for-synchronous-methods/
Re[3]: WCF Stream => FileStream Async
От: takTak  
Дата: 01.04.21 06:14
Оценка:
S>А клиент то что увидит? Он true также получит не раньше, когда копирование закончится.

не совсем понятно, к чему это?
изначальная цель была сделать из синхронного вызова асинхронный: речь идёт о масштабируемости на стороне сервера, при чём здесь клиент?
Re[4]: WCF Stream => FileStream Async
От: varenikAA  
Дата: 01.04.21 06:24
Оценка:
Здравствуйте, takTak, Вы писали:

S>>А клиент то что увидит? Он true также получит не раньше, когда копирование закончится.


T>не совсем понятно, к чему это?

T>изначальная цель была сделать из синхронного вызова асинхронный: речь идёт о масштабируемости на стороне сервера, при чём здесь клиент?
Мне тоже показалось, что ТС хочет отпустить клиента вернув тру и уже самостоятельно обработать стрим. Но он видимо не догадывается о том, стрим он вот так сразу не улетает в космос.
Хотя может быть вопрос просто корявый.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re: WCF Stream => FileStream Async
От: varenikAA  
Дата: 01.04.21 06:30
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>Всем привет!


D>Есть примерно такой рабочий код:


Еще раз подумав, хочу залать вопрос зачем вам асинх? Если клиент колом встает, то и асинку надо на клиенте лепить.
можно и там и там. иначе никак.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[5]: WCF Stream => FileStream Async
От: takTak  
Дата: 01.04.21 06:39
Оценка: 4 (1) +1
S>>>А клиент то что увидит? Он true также получит не раньше, когда копирование закончится.

T>>не совсем понятно, к чему это?

T>>изначальная цель была сделать из синхронного вызова асинхронный: речь идёт о масштабируемости на стороне сервера, при чём здесь клиент?
AA>Мне тоже показалось, что ТС хочет отпустить клиента вернув тру и уже самостоятельно обработать стрим. Но он видимо не догадывается о том, стрим он вот так сразу не улетает в космос.
AA>Хотя может быть вопрос просто корявый.

1) если так, до достаточно , наверное, просто забыть про await на стороне клиента, если будут какие-то исключения на стороне сервера, о них клиент не узнает

2) ThreadPool.QueueUserWorkItem(async o => await FireAndForget());

3) Task.Factory.StartNew(async () => await FireAndForget()); что аналогично Task.Run, но на стороне сервера такое делать неэффективно
Re[4]: WCF Stream => FileStream Async
От: Sharov Россия  
Дата: 01.04.21 11:42
Оценка:
Здравствуйте, takTak, Вы писали:

S>>А клиент то что увидит? Он true также получит не раньше, когда копирование закончится.


T>не совсем понятно, к чему это?

T>изначальная цель была сделать из синхронного вызова асинхронный: речь идёт о масштабируемости на стороне сервера, при чём здесь клиент?

На сколько я понял, принимаем поток, возвращаем true и асинхронно его сохраняем. Т.е. клиент узнает (true) о факте
приема, а не о конечном результате. Ну так я понял пожелание ТС. А на счет масштабируемости -- вроде так и так
будет поток на запрос.
Кодом людям нужно помогать!
Re[6]: WCF Stream => FileStream Async
От: Sharov Россия  
Дата: 01.04.21 16:37
Оценка:
Здравствуйте, takTak, Вы писали:

T>3) Task.Factory.StartNew(async () => await FireAndForget()); что аналогично Task.Run, но на стороне сервера такое делать неэффективно


А почему не просто
Task.Factory.StartNew(() => FireAndForget() );, иначе -- стартануть поток, чтобы стартануть поток. Зачем?
Кодом людям нужно помогать!
Re[7]: WCF Stream => FileStream Async
От: takTak  
Дата: 01.04.21 18:37
Оценка: +1
T>>3) Task.Factory.StartNew(async () => await FireAndForget()); что аналогично Task.Run, но на стороне сервера такое делать неэффективно

S>А почему не просто

S>Task.Factory.StartNew(() => FireAndForget() );, иначе -- стартануть поток, чтобы стартануть поток. Зачем?

я исходил из того, что FireAndForget- асинхронный метод и по привычке добавил async — await, хотя если ждать не нужно и ошибки тоже не интересуют, это излишнее,

кстати, Task.Factory.StartNew — более общий случай, чем Task.Run, но в 99% случаев лучше использовать Task.Run
Re[5]: WCF Stream => FileStream Async
От: mDmitriy Россия  
Дата: 03.04.21 13:52
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Мне тоже показалось, что ТС хочет отпустить клиента вернув тру и уже самостоятельно обработать стрим. Но он видимо не догадывается о том, стрим он вот так сразу не улетает в космос.

AA>Хотя может быть вопрос просто корявый.
ну вот и подскажите, плиз, раз уж вы в теме:
мне нужно чтобы клиент получал Ок как только весь стрим примет сервер
Re[2]: WCF Stream => FileStream Async
От: mDmitriy Россия  
Дата: 03.04.21 13:59
Оценка:
Здравствуйте, varenikAA, Вы писали:

AA>Еще раз подумав, хочу залать вопрос зачем вам асинх? Если клиент колом встает, то и асинку надо на клиенте лепить.

AA>можно и там и там. иначе никак.
грубо говоря — клиент не должен ждать, что поток где-то там запишется на диск с неизвестной скоростью
он должен отправить весь поток и получить ОК
или ошибку, что сервер поток не получил
что там делает дальше с потоком сервер — не его забота
Re[3]: WCF Stream => FileStream Async
От: varenikAA  
Дата: 04.04.21 04:06
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>Здравствуйте, varenikAA, Вы писали:


AA>>Еще раз подумав, хочу залать вопрос зачем вам асинх? Если клиент колом встает, то и асинку надо на клиенте лепить.

AA>>можно и там и там. иначе никак.
D>грубо говоря — клиент не должен ждать, что поток где-то там запишется на диск с неизвестной скоростью
D>он должен отправить весь поток и получить ОК
D>или ошибку, что сервер поток не получил
D>что там делает дальше с потоком сервер — не его забота

Клиент просто должен сделать выполнить вызов сервера асинхронным, оберни
его в _ = Task.Run( () => ApiInstance.ProcessStream(streamObj));
в C# не нужно специально проверять дошел ли стрим до сервера. будет исключение если случится ошибка.
Вот исключение и надо ловить внутри вызова Task.Run( () => try {ApiInstance.ProcessStream(streamObj);catch ...);
Главное чтобы стрим на клиенте жил до конца передачи, то есть случайно не вызвать диспоуз.
Совет как-то идентифицировать сообщения, чтобы проверять без повторной передачи, что стрим уже передан ранее на случай сетевых сбоев.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[4]: WCF Stream => FileStream Async
От: mDmitriy Россия  
Дата: 04.04.21 06:12
Оценка:
AA>Клиент просто должен сделать выполнить вызов сервера асинхронным, оберни
не понял — клиенту это зачем?
клиент должен дождаться конца отправки потока, остальное его не интересует

AA>Главное чтобы стрим на клиенте жил до конца передачи, то есть случайно не вызвать диспоуз.

как раз синхронный вызов и ожидание его завершения это и обеспечит

AA>Совет как-то идентифицировать сообщения, чтобы проверять без повторной передачи, что стрим уже передан ранее на случай сетевых сбоев.

это не нужно в конкретном случае, при неудаче достаточно зафиксировать ошибку

меня вообще интересует сервер и только сервер
чтобы он быстрее обрабатывал и отпускал запрос
Re[5]: WCF Stream => FileStream Async
От: varenikAA  
Дата: 04.04.21 08:56
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>меня вообще интересует сервер и только сервер

D>чтобы он быстрее обрабатывал и отпускал запрос

Быстрее чем клиент передаст стрим не получится.
Успешная запись стрима на сервере и будет логикой успешного завершения операции.
☭ ✊ В мире нет ничего, кроме движущейся материи.
Re[6]: WCF Stream => FileStream Async
От: mDmitriy Россия  
Дата: 04.04.21 11:30
Оценка:
Здравствуйте, varenikAA, Вы писали:
AA>Быстрее чем клиент передаст стрим не получится.
AA>Успешная запись стрима на сервере и будет логикой успешного завершения операции.

имеет ли тогда смысл синхронно сохранить стрим на сервере в память (MemoryStream),
вернуть клиенту Ок
а потом неспешно и асинхронно писать из MemoryStream на диск?
Re[7]: WCF Stream => FileStream Async
От: Sharov Россия  
Дата: 04.04.21 13:33
Оценка:
Здравствуйте, mDmitriy, Вы писали:


D>имеет ли тогда смысл синхронно сохранить стрим на сервере в память (MemoryStream),

D>вернуть клиенту Ок
D>а потом неспешно и асинхронно писать из MemoryStream на диск?

Зависит от. Если приложение нагруженное, то нет конечно. Т.е. есть два варианта-- буфферизировать, и тогда по факту получения всех данных отпускать клиента, либо -- полученные данные сразу потоком писать на диск, возможно, асинхронно. Буфферизация кажется быстрее, нету работы с диском, но можно как-то и асинхронно сделать и с потоком напрямую.
Кодом людям нужно помогать!
Re[7]: WCF Stream => FileStream Async
От: varenikAA  
Дата: 05.04.21 11:45
Оценка:
Здравствуйте, mDmitriy, Вы писали:

D>имеет ли тогда смысл синхронно сохранить стрим на сервере в память (MemoryStream),

D>вернуть клиенту Ок
D>а потом неспешно и асинхронно писать из MemoryStream на диск?
Клиент получил ок, а на последнем шаге бамп!!! не записался стрим.
Что тогда, в асинхронке без айди сообщения никуда, посмотрите как это реализовано в kafka.
☭ ✊ В мире нет ничего, кроме движущейся материи.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.