问题描述
我已经看到了很多类似这样的其他问题,但并没有发现我的答案在那里。
I have seen numerous other questions similar to this but did not find my answer there.
我的问题是,我是创建具有以下流线:
My problem was that I was creating threads with the following flow:
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);
}
在这种方式,我的每一个服务的异步方法会回调,他们最初呼吁线程(通常是UI线程)。所以,我模拟如何计谋/异步关键字的工作(我不能用.NET 4.5)。
In this way, each of my service's asynchronous methods would callback the thread they were originally called on (generally the UI thread). So I am simulating how the await/async keywords work (I cannot use .NET 4.5).
这种模式的问题是,我得到莫名其妙地锁定在UI线程第一次调用ContinueWith之后。因此,在这种情况下,如果我试图产卵5线程每个进程的同步功能获取,他们将执行1:1,而不是并行,甚至他们是否会阻止用户界面线程,而这样做,我请尝试指定TaskCreationOptions.LongRunning。
The problem with this pattern is that I get inexplicably locked to the UI thread after the first call to "ContinueWith". So in this case if I attempt to spawn 5 threads to each process a synchronous function Get, they will execute 1 by 1 instead of in parallel and they will block the UI thread while doing so, even if I try specifying TaskCreationOptions.LongRunning.
这永远不会发生与我为Task.Factory.StartNew第一个电话,它只是发生在后续调用从第一个回调中
This never happens with my first call to Task.Factory.StartNew, it only happens to subsequent calls from within the first callback.
推荐答案
为了强制推出一个新的线程,你应该在调用Task.Factory.StartNew指定TaskScheduler.Default如下:
In order to force the launch of a new thread, you should specify TaskScheduler.Default in the call to Task.Factory.StartNew as follows:
Task.Factory.StartNew(action,
CancellationToken.None,
TaskCreationOptions.None,
TaskScheduler.Default).ContinueWith(completeAction);
在我的测试中,你不需要为了逼后台线程指定TaskCreationOptions.LongRunning,但它不应该受到伤害。
In my testing you do not need to specify TaskCreationOptions.LongRunning in order to force a background thread, though it shouldn't hurt.
这篇关于如何强制Task.Factory.StartNew到后台线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!