Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.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#_.net_Multithreading - Fatal编程技术网

C# 在以下或类似的场景中如何避免线程等待(如果确实有必要,想让线程等待)?

C# 在以下或类似的场景中如何避免线程等待(如果确实有必要,想让线程等待)?,c#,.net,multithreading,C#,.net,Multithreading,请参阅下面的代码片段。我试图执行一个长时间运行的任务,但我不想等待超过给定的超时时间。我想完全控制任务何时开始,因此生成一个新线程并完成工作,然后在父线程中等待它。该模式确实有效,但父线程只是在等待。理想情况下,我不喜欢线程睡眠/等待它真正需要的。我怎样才能做到这一点?欢迎提出任何建议/想法/模式 /// <summary> /// tries to execute a long running task /// if the task is not completed in spe

请参阅下面的代码片段。我试图执行一个长时间运行的任务,但我不想等待超过给定的超时时间。我想完全控制任务何时开始,因此生成一个新线程并完成工作,然后在父线程中等待它。该模式确实有效,但父线程只是在等待。理想情况下,我不喜欢线程睡眠/等待它真正需要的。我怎样才能做到这一点?欢迎提出任何建议/想法/模式

/// <summary>
/// tries to execute a long running task
/// if the task is not completed in specified time, its deemed un-sccessful.
/// </summary>
/// <param name="timeout"></param>
/// <returns></returns>
bool Task(int timeout)
{
    bool workCompletedSuccessfully = false;
    //I am intentionally spawning thread as i want to have control when the thread start
    //so not using thread pool threads.
    Thread t = new Thread(() =>
    {
        //executes some long running task
        //handles all the error conditions
        //ExecuteTask();
        workCompletedSuccessfully = true;
    });
    t.Start();
    //cannot wait more "timeout"                        
    //My main thread (parent) thread simply waiting for the spawened thread to join
    //HOW CAN I AVOID THIS?ANY PATTERN TO AVOID THIS REALLY HELPS?
    t.Join(timeout);
    if (!workCompletedSuccessfully)
    {
        //deeemed un-successful
        //do the remediation by gracefully disposing the thread
        //itnentionally hidden details about disposing thread etc, to concentrate on 
        //the question - AVOIDING PARENT THREAD TO WAIT
    }
    return workCompletedSuccessfully;
}
//
///尝试执行长时间运行的任务
///如果任务未在规定时间内完成,则视为未成功。
/// 
/// 
/// 
布尔任务(整数超时)
{
bool workCompletedSuccessfully=false;
//我有意生成线程,因为我希望在线程启动时拥有控制权
//所以不要使用线程池线程。
线程t=新线程(()=>
{
//执行一些长时间运行的任务
//处理所有错误条件
//ExecuteTask();
workCompletedSuccessfully=true;
});
t、 Start();
//无法再等待“超时”
//我的主线程(父线程)只是等待spawened线程加入
//我怎样才能避免这种情况呢?有什么模式可以避免这种情况吗?
t、 加入(超时);
如果(!workCompletedSuccessfully)
{
//被认为不成功
//通过优雅地处理线程来执行修复
//它在很大程度上隐藏了关于处理线程等的详细信息
//问题-避免父线程等待
}
返回workCompletedSuccessfully;
}
问候,, 梦想家

使用

我在这里看到的唯一问题是,您计划如何处理未按时完成的线程。理论上,您可以调用
Thread.Abort()
,但这不是一个好主意,因为它会破坏应用程序的状态


编辑:您需要了解
threadFinished.WaitOne(超时)
仍处于阻塞状态,但时间不长于
timeout

您希望如何优雅地处理尚未完成其工作的线程?无论如何,我不确定您是否可以让父线程执行有意义的操作,并以任何直接的方式接收超时通知。(也就是说,不需要让父线程通过可以接收“task successful”或“task timed out”事件的事件循环来工作。)既然如此,那该如何工作呢?父线程是否应该中断它正在执行的任何操作并处理通知?也许这有助于@I4V这个好主意,但它显然需要“异步化”整个代码库。(一个非平凡的更改,但可能是正确的调用。)@millimoose是的,它要求切换到TPL库,但异步/等待不是必须的。我认为OP想要的是摆脱父线程的等待-即让它继续工作,但也会被通知超时发生。@millimoose可能。让我们看看他说了什么。@millimoose如果这是他真正想要的,他可以将我的代码包装到线程中并启动。嗨,Andrey,谢谢你的快速响应。但是,即使是threadFinished.waitone(超时)也会阻止父线程。不是吗?它只是相同模式的变体,使用事件而不是thread.join()。换句话说,我们希望避免thread.join()或event.waitone(),因为父线程只是等待什么也不做。当做Dreamer@Dreamer是的,它阻塞了。要使其无阻塞,只需在另一个线程中运行我的代码。因此,您将有3个线程,UI线程、watcher线程和worker线程。
bool Task(int timeout)
{
    AutoResetEvent threadFinished = new AutoResetEvent(false);
    //I am intentionally spawning thread as i want to have control when the thread start
    //so not using thread pool threads.
    Thread t = new Thread(() =>
    {
        //executes some long running task
        //handles all the error conditions
        //ExecuteTask();
        threadFinished.Set();
    });
    t.Start();
    //Param - timeout
    bool finished = threadFinished.WaitOne(timeout);
    if (!finished)
    {
        //deeemed un-successful
        //do the remediation by gracefully disposing the thread
    }
    return finished;
}