像下面这样的代码将启动一个新线程来完成这项工作.有什么方法可以控制该线程的优先级吗?
Task.Factory.StartNew(() => {
// everything here will be executed in a new thread.
// I want to set the priority of this thread to BelowNormal
});
Run Code Online (Sandbox Code Playgroud) 显然TaskFactory.StartNew,.NET 4.0中的方法旨在替代ThreadPool.QueueUserWorkItem(根据这篇文章,无论如何).我的问题很简单:有谁知道为什么?
是否TaskFactory.StartNew有更好的表现?它使用更少的内存吗?或者它主要是为了Task班级提供的附加功能?在后一种情况下,StartNew可能会有比较差的表现QueueUserWorkItem吗?
在我看来,StartNew实际上可能会使用更多的内存QueueUserWorkItem,因为它会Task在每次调用时返回一个对象,我希望这会导致更多的内存分配.
无论如何,我很想知道哪种更适合高性能场景.
我想知道在使用TPL TaskFactory.FromAsync和使用TaskFactory.StartNew阻塞版本的方法之间是否存在性能影响.我正在编写一个TCP服务器,它将支持不超过100个并发连接.在使用第一个选项编写代码并使用continue来链接多个读写操作之后,我留下了丑陋,难以调试的代码.
我相信用同步版本编写代码然后用Task包装它会降低复杂性并提高可测试性,但是我担心这样做的性能影响.
例如,这两个调用之间是否存在任何性能差异:
NetworkStream stream;
byte[] data;
int bytesRead;
//using FromAsync
Task<int> readChunk = Task<int>.Factory.FromAsync (
stream.BeginRead, stream.EndRead,
data, bytesRead, data.Length - bytesRead, null);
//using StartNew with blocking version
Task<int> readChunk2 = Task<int>.Factory.StartNew(() =>
stream.Read(data, bytesRead, data.Length - bytesRead));
Run Code Online (Sandbox Code Playgroud) 我在使用时遇到了一个问题,Task.Factory.StartNew并试图捕获exception被抛出的问题.在我的应用程序中,我有一个长期运行的任务,我想封装在一个Task.Factory.StartNew(.., TaskCreationOptions.LongRunning);
但是,当我使用时,没有捕获异常Task.Factory.StartNew.然而,当我使用时Task.Run,它正如我所期望的那样工作,我认为它只是一个包装器Task.Factory.StartNew(根据例如这篇MSDN文章).
这里提供了一个工作示例,不同之处在于在使用时将异常写入控制台Task.Run,但在使用时不会Factory.StartNew.
我的问题是:
如果我有一个LongRunning可以抛出异常的任务,我应该如何在调用代码中处理它们?
private static void Main(string[] args)
{
Task<bool> t = RunLongTask();
t.Wait();
Console.WriteLine(t.Result);
Console.ReadKey();
}
private async static Task<bool> RunLongTask()
{
try
{
await RunTaskAsync();
}
catch (Exception e)
{
Console.WriteLine(e);
return false;
}
Console.WriteLine("success");
return true;
}
private static Task RunTaskAsync()
{
//return Task.Run(async () =>
// {
// throw new Exception("my exception");
// }); …Run Code Online (Sandbox Code Playgroud) 我需要创建一个将替换Windows窗体窗口中的照片的线程,而不是等待〜1秒并恢复上一张照片.
我以为代码如下:
TaskScheduler ui = TaskScheduler.FromCurrentSynchronizationContext();
var task = Task.Factory.StartNew(() =>
{
pic.Image = Properties.Resources.NEXT;
Thread.Sleep(1000);
pic.Image = Properties.Resources.PREV;
}, CancellationToken.None, TaskCreationOptions.LongRunning, ui)
Run Code Online (Sandbox Code Playgroud)
做的工作,但不幸的是没有.它冻结了主UI线程.
那是因为并不能保证每个任务都有一个线程.一个线程可用于处理多个任务.即使TaskCreationOptions.LongRunning选项也无济于事.
我怎么解决它?
我使用任务库来进行图像压缩服务.我想压缩许多文件的并发性.但是我希望服务仅在用户空闲时运行(或者在程序中没有更多的任务).
我知道threadPool不支持"更改线程优先级"功能,因此任务也支持此功能.
我可以在更高级别的控制上开发该功能吗?(例如,TaskScheduler优先级)
我试图测试一些依赖于Task进行一些后台计算的类(从网络位置检索数据).该类获取一个未启动的Task实例,添加一个ContinueWith方法,然后在Task上调用Start.像这样的东西:
private void Search()
{
Task<SearchResults> searchTask = m_searchProvider.GetSearchTask(m_searchCriteria);
searchTask.ContinueWith(OnSearchTaskCompleted);
searchTask.Start();
}
Run Code Online (Sandbox Code Playgroud)
该类通过接口获取Task的实例,因此我能够注入我的测试所控制的Task实例.但是,我似乎无法创建一个我有足够控制权的人.
我不想在测试中引入线程,但仍希望使Task以异步方式运行,所以我试图做的是编写一个实现BeginInvoke/EndInvoke模式的类而不进行线程化,并使用TaskFactory.FromAsync方法创建任务.
想法是测试可以在启动任务的类上调用方法,然后当返回测试时,可以将结果数据提供给Async对象,该对象在保持同一线程的同时完成操作.
但是,当我尝试在该任务上调用Start时,我收到一条错误消息,指出"可能无法在具有空操作的任务上调用Start".不幸的是,谷歌对这条消息没什么帮助,所以我不确定我是否错误地实现了我的Async对象,或者错误地使用了TaskFactory.FromAsync.这是我的NonThreadedAsync类的代码和一个异常的测试:
public class NonThreadedAsync<TResult>
{
private NonThreadedAsyncResult<TResult> m_asyncResult;
public IAsyncResult BeginInvoke(
AsyncCallback callback,
object state)
{
m_asyncResult = new NonThreadedAsyncResult<TResult>(callback, state);
return m_asyncResult;
}
public TResult EndInvoke(IAsyncResult asyncResult)
{
return m_asyncResult.GetResults();
}
public void Complete(TResult data)
{
m_asyncResult.CompleteAsync(data);
}
}
public class NonThreadedAsyncResult<TResult> : IAsyncResult
{
private readonly AsyncCallback m_asyncCallback;
private readonly object m_state;
private readonly ManualResetEvent m_waitHandle;
private bool m_isCompleted;
private TResult m_resultData;
public …Run Code Online (Sandbox Code Playgroud) 我想在包含操作的任务中添加多个参数。我查看了现有的堆栈溢出问题Create a Task with an Action<T>
请帮助我如何在任务的 Action 方法中传递多个参数
Action<string, int> action = (string msg, int count) =>
{
Task.Factory.StartNew(async () =>
{ await LoadAsync(msg, count); });
};
Task task = new Task(action, ....);
Run Code Online (Sandbox Code Playgroud)
动作方法是
public static async Task<string> LoadAsync(string message, int count)
{
await Task.Run(() => { Thread.Sleep(1500); });
Console.WriteLine("{0} {1} Exceuted Successfully !", message ?? string.Empty, (count == 0) ? string.Empty : count.ToString());
return "Finished";
}
Run Code Online (Sandbox Code Playgroud)
请帮助我如何创建异步方法的操作以及如何将操作添加到任务中。
我有一个关于多线程应用程序的问题.我使用TaskFactory来启动一个cpu +时间密集型方法.此方法是对SAP的调用,需要很长时间才能完成.用户应该有一个取消任务的选项.目前我正在使用thread.Abort(),但我知道这种方法不是取消它的最佳解决方案.有没有人有替代方案的建议?
代码示例:
Form_LoadAction loadbox = new Form_LoadAction();
Thread threadsapquery = null;
Task.Factory.StartNew<>(() =>
{
t = Thread.CurrentThread;
Thread.sleep(10000000000); //represents time + cpu intensive method
}
loadbox.ShowDialog();
if (loadbox.DialogResult == DialogResult.Abort)
{
t.Abort();
}
Run Code Online (Sandbox Code Playgroud) 使用TaskFactory时遇到一些奇怪的事情:
Task<int[]> parent = Task.Run(() =>
{
int length = 100;
var results = new int[length];
TaskFactory tf = new TaskFactory(TaskCreationOptions.AttachedToParent,
TaskContinuationOptions.ExecuteSynchronously);
// Create a list of tasks that we can wait for
List<Task> taskList = new List<Task>();
for (int i = 0; i < length - 1; i++) // have to set -1 on length else out of bounds exception, huh?
{
taskList.Add(tf.StartNew(() => results[i] = i));
}
// Now wait for all tasks to complete
Task.WaitAll(taskList.ToArray());
return results; …Run Code Online (Sandbox Code Playgroud) taskfactory ×10
c# ×6
task ×5
.net ×4
c#-4.0 ×3
.net-4.0 ×1
abort ×1
delegates ×1
exception ×1
performance ×1
sleep ×1
thread-abort ×1
threadpool ×1
winforms ×1