Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在特殊线程上运行进程并等待结果_C#_Multithreading_Task Parallel Library_Stack Overflow - Fatal编程技术网

C# 在特殊线程上运行进程并等待结果

C# 在特殊线程上运行进程并等待结果,c#,multithreading,task-parallel-library,stack-overflow,C#,Multithreading,Task Parallel Library,Stack Overflow,我有一个简单的代码 var map=新的参考实体容量UOW; ... 这很好 但是现在,由于它的递归性,我需要在另一个具有较大堆栈大小的线程上运行它,并在继续之前等待它的结果 最简单的方法是什么? 我看不出有什么方法可以给任务指定一个特定的线程,或者告诉它创建一个具有大堆栈的线程 背景(如需要): 上面我已经使用了几个月的代码突然开始抛出堆栈溢出异常。我相信我刚刚达到了一个极限,因为它现在正在处理近140k个具有关系的实体,以决定它们在初始化新数据库时应该保存的顺序。 我不能改变递归部分——它位

我有一个简单的代码

var map=新的参考实体容量UOW; ... 这很好

但是现在,由于它的递归性,我需要在另一个具有较大堆栈大小的线程上运行它,并在继续之前等待它的结果

最简单的方法是什么? 我看不出有什么方法可以给任务指定一个特定的线程,或者告诉它创建一个具有大堆栈的线程

背景(如需要): 上面我已经使用了几个月的代码突然开始抛出堆栈溢出异常。我相信我刚刚达到了一个极限,因为它现在正在处理近140k个具有关系的实体,以决定它们在初始化新数据库时应该保存的顺序。 我不能改变递归部分——它位于我使用的外部第三方库中,我没有更新它的计划

我已经破解了测试代码,以证明它在大型堆栈线程上进行处理时确实有效。

您可以将线程类与maxStackSize构造函数一起使用,但如果您想保持任务语义,则必须实现自定义TaskScheduler,如下所示:

public class BigStackTaskScheduler : TaskScheduler
{
    private int _stackSize;

    public BigStackTaskScheduler(int stackSize)
    {
        _stackSize = stackSize;
    }

    // we don't need to keep a tasks queue here
    protected override IEnumerable<Task> GetScheduledTasks()
    {
        return new Task [] { };
    }

    protected override void QueueTask(Task task)
    {
        var thread = new Thread(ThreadWork, _stackSize);
        thread.Start(task);
    }

    // we aren't going to inline the execution
    protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
    {
        QueueTask(task);
        return false;
    }

    private void ThreadWork(object obj)
    {
        if (obj is Task task)
            TryExecuteTask(task);
    }
}

class Program
{
    async static Task Test()
    {
        var taskFactory = new TaskFactory(
            CancellationToken.None, TaskCreationOptions.DenyChildAttach,
            TaskContinuationOptions.None, new BigStackTaskScheduler(0xffff * 2));
        await taskFactory.StartNew(() => { Console.WriteLine("Task"); });
    }

    static void Main(string[] args)
    {
        Test().Wait();
    }
}

对我来说,增加堆栈大小似乎是一种恶作剧,而且这种恶作剧在将来只会再次发生。你不能重构代码使其不是递归的吗?你可以手动创建一个新线程,或者使用Task.Factory.StartNew的TaskCreationOptions.LongRunning选项强制使用一个专用线程。我特别包括了背景文本,说重构递归是不可能的——不是我的代码!Longlung不行,它必须有一个巨大的堆栈。这段代码只需要一两秒钟的时间就可以运行,只是在试图处理这些实体时,它自己消失了。这段代码只用于将数据导入到新的数据库中。从那以后就再也不会有问题了。这些看起来很有希望,我明天第一件事就是要看一看,但我承认我对Tasks/wait/async不太熟悉。在Main中,我将有一个UOW-UOW实例,我希望将它传递给在这个bigstack线程上运行的方法,该方法将返回一个MAP-MAP实例,这样我就可以在Main的线程上处理它。我想我可以试着用Func而不是Action来重构你的上一段代码,这样它就变得通用了。@SimonHewitt,我修改了TaskCompletionSource示例,使其更通用。请演示Func.Super的可能用法!我的一行代码被一行代码替换:var map=ThreadWithCustomStackuowArg=>newreferencedentitypapaceuowarg,uow,1_0000_000.Result;
class Program
{
    static Task<TOut> ThreadWithCustomStack<TIn, TOut>(Func<TIn, TOut> action, TIn arg, int stackSize)
    {
        var tcs = new TaskCompletionSource<TOut>();

        var thread = new Thread(new ThreadStart(() => 
        {
            try
            {
                tcs.SetResult(action(arg));
            }
            catch (Exception e)
            {
                tcs.SetException(e);
            }
        }), stackSize);

        thread.Start();
        thread.Join();

        return tcs.Task;
    }

    async static Task Test()
    {
        var result = await ThreadWithCustomStack(
            arg => { Console.WriteLine("Task"); return arg.ToString(); }, 
            2, 
            0xffff * 2);
    }

    static void Main(string[] args)
    {
        Test().Wait();
    }
}