Widziałem wiele innych pytań podobnych do tego, ale nie znalazłem tam odpowiedzi.Jak zmusić Task.Factory.StartNew do wątku tła?
Moim problemem było to, że było stworzenie wątki z następującym przepływu:
private void btn_Click(object sender, EventArgs e)
{
service.GetCount(
(count, ex) =>
{
if (ex != null)
return;
for (int i = 0; i < count; i++)
{
service.Get(onItemReceived, i);
}
}
);
}
public void GetCount(Action<int, Exception> callback)
{
var callingThread = TaskScheduler.FromCurrentSynchronizationContext();
Func<int> action =() =>
{
return client.GetCount(); // Synchronous method, could take a long time
};
Action<Task<int>> completeAction = (task) =>
{
Exception ex = (task.Exception != null) ? task.Exception.InnerException : task.Exception;
if (callback != null)
callback(task.Result, ex);
};
Task.Factory.StartNew(action).ContinueWith(completeAction, callingThread);
}
public void Get(Action<object, Exception> callback, int index)
{
var callingThread = TaskScheduler.FromCurrentSynchronizationContext();
Func<object> action =() =>
{
return client.Get(index); // Synchronous method, could take a long time
};
Action<Task<object>> completeAction = (task) =>
{
Exception ex = (task.Exception != null) ? task.Exception.InnerException : task.Exception;
if (callback != null)
callback(task.Result, ex);
};
Task.Factory.StartNew(action).ContinueWith(completeAction, callingThread);
}
W ten sposób, każda z metod asynchronicznych moją usługę byłby callback nić były pierwotnie zwany na (zwykle wątku UI). Tak więc symuluję działanie słów kluczowych oczekujących/asynchronicznych (nie mogę używać programu .NET 4.5).
Problem z tym wzorcem polega na tym, że po pierwszym wywołaniu komunikatu "ContinueWith" otrzymuję niewytłumaczalną blokadę do wątku interfejsu użytkownika. Tak więc w tym przypadku, jeśli spróbuję odrodzić 5 wątków dla każdego procesu funkcji synchronicznej, będą one wykonywać 1 zamiast 1 zamiast równolegle i będą blokować wątek UI podczas tego procesu, nawet jeśli spróbuję określić TaskCreationOptions.LongRunning .
To się nigdy nie zdarza z moim pierwszym wywołaniem Task.Factory.StartNew, to zdarza się tylko w następnych połączeniach od wewnątrz pierwszego wywołania zwrotnego.
Możliwe duplikaty [Jak zagwarantować nowy wątek jest tworzony przy użyciu metody Task.StartNew] (https://stackoverflow.com/questions/8039936/how-to-guarantee-a-new-thread-is- create-when-using-the-task-startnew-method) –