Код, который должен создать объект, отправить id, а затем обработать в бд. Проблема в том, что я не понимаю как Сначала вернуть ответ, а уже потом работать с этим объектом в БД.
// POST /task
[HttpPost]
public IActionResult Post([FromBody]string value)
{
Task task = new Task { Id = Guid.NewGuid(), Status = "created", Time = DateTime.Now };
db.Tasks.Add(task);
db.SaveChanges();
//await WaitTwoMinutesAndFinish();
System.Threading.Tasks.Task t = new System.Threading.Tasks.Task(() =>
{
using (db)
{
var result = db.Tasks.SingleOrDefault(x => x.Id == task.Id);
if (result != null)
{
result.Status = "running";
result.Time = DateTime.Now;
db.SaveChanges();
}
//else
//return 1;
Thread.Sleep(3000);
// status = finished
result.Status = "finished";
result.Time = DateTime.Now;
db.SaveChanges();
}
});
t.Start();
//UpdateRecord(task);
return Accepted(task.Id);
}
Но когда я отсылаю запрос, то вылетает исключение (в строке var result):
Cannot access a disposed object.
A common cause of this error is disposing a context that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application.
This may occur if you are calling Dispose() on the context, or wrapping the context in a using statement.
If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Если не интересоваться, зачем это вообще нужно, то можно написать вот такой метод
private async Task MyMethod(int taskId)
{
using (var db = new MyDbContext())
{
var result = await db.Tasks.SingleOrDefaultAsync(x => x.Id == task.Id);
if (result != null)
{
result.Status = "running";
result.Time = DateTime.Now;
await db.SaveChangesAsync();
}
//else
//return 1;
await Task.Delay(3000);
// status = finished
result.Status = "finished";
result.Time = DateTime.Now;
await db.SaveChangesAsync();
}
}
и вызвать его из вашего кода так
MyMethod(task.Id)
Это не создаст нового треда и должно отработать. Но зачем вообще это делать мне не ясно.
Чтобы иметь возможность создать контекст данных, можно прокинуть сервис провайдер, который является контейнером по умолчанию. Пример как это делать:
[Route("api/[controller]")]
public class ValuesController : Controller
{
private IServiceProvider _serviceProvider;
public ValuesController(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}
// GET api/values
[HttpGet]
public IEnumerable<string> Get()
{
Foo();
return new string[] { "value1", "value2" };
}
private async void Foo()
{
using(var db = (MyDataContext)_serviceProvider.GetService(typeof(MyDataContext)))
{
await db.SaveChangesAsync();
}
}
}
Апостиль в Лос-Анджелесе без лишних нервов и бумажной волокиты
Основные этапы разработки сайта для стоматологической клиники
Продвижение своими сайтами как стратегия роста и независимости