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_Concurrency_Waithandle - Fatal编程技术网

如何在C#中等待线程完成执行?

如何在C#中等待线程完成执行?,c#,multithreading,concurrency,waithandle,C#,Multithreading,Concurrency,Waithandle,我有一个快速连续调用的函数,它有一个开放的数据库连接。 我的问题是,在关闭一个数据库连接之前,调用该函数的另一个实例,我可能会收到数据库中的死锁 我试过: private static WaitHandle[] waitHandles = new WaitHandle[] { new AutoResetEvent(false) }; protected override void Broadcast(Data data, string updatedBy)

我有一个快速连续调用的函数,它有一个开放的数据库连接。 我的问题是,在关闭一个数据库连接之前,调用该函数的另一个实例,我可能会收到数据库中的死锁

我试过:

private static WaitHandle[] waitHandles = new WaitHandle[]
    {
        new AutoResetEvent(false)
    };

protected override void Broadcast(Data data, string updatedBy)
    {
        Action newAction = new Action(() =>
        {
        DataManagerFactory.PerformWithDataManager( 
            dataManager =>
            {
                // Update status and broadcast the changes
                data.UpdateModifiedColumns(dataManager, updatedBy);

                BroadcastManager.Instance().PerformBroadcast(
                    data,
                    BroadcastAction.Update,
                    Feature.None);
            },
            e => m_log.Error(ServerLog.ConfigIdlingRequestHandler_UpdateFailed() + e.Message));
            }
        );

        Thread workerThread = new Thread(new ThreadStart(newAction));
        ThreadPool.QueueUserWorkItem(workerThread.Start, waitHandles[0]);
        WaitHandle.WaitAll(waitHandles);
    }
但是我收到一个线程错误,程序冻结了。我相信这与线程启动函数没有参数有关


谢谢你的帮助

就是这样做的。创建执行作业的类:

public class MyAsyncClass
{

    public delegate void NotifyComplete(string message);
    public event NotifyComplete NotifyCompleteEvent;

    //Starts async thread...
    public void Start()
    {
        System.Threading.Thread t = new System.Threading.Thread(new System.Threading.ThreadStart(DoSomeJob));
        t.Start();
    }

    void DoSomeJob()
    {
        //just wait 5 sec for nothing special...
        System.Threading.Thread.Sleep(5000);
        if (NotifyCompleteEvent != null)
        {
            NotifyCompleteEvent("My job is completed!");
        }
    }
}
这是另一个类的代码,调用第一个类:

 MyAsyncClass myClass = null;


    private void button2_Click(object sender, EventArgs e)
    {
        myClass = new MyAsyncClass();
        myClass.NotifyCompleteEvent += new MyAsyncClass.NotifyComplete(myClass_NotifyCompleteEvent);
        //here I start the job inside working class...
        myClass.Start();
    }

    //here my class is notified from working class when job is completed...
    delegate void myClassDelegate(string message);
    void myClass_NotifyCompleteEvent(string message)
    {
        if (this.InvokeRequired)
        {
            Delegate d = new myClassDelegate(myClass_NotifyCompleteEvent);
            this.Invoke(d, new object[] { message });
        }
        else
        {
            MessageBox.Show(message);
        }
    }
如果我需要解释一些细节,请告诉我


另一种选择是:

QueueUserWorkItem中的第二个对象是参数。请参阅通常情况下,您不会将新线程的
Start
方法排入
ThreadPool
队列。那有点违背目的。只需排队
newAction
。您可能应该锁定可能导致服务器端死锁的任何方法(
PerformBroadcast
?)。ThreadPool.QueueUserWorkItem(newAction,null);不起作用。QueueUserWorkItem(newAction,waitHandles[0]);不起作用。我只是等待线程结束。我不想有一个自定义类,也不想使用动作触发的等待方法。有什么关于等待线程的提示吗?之后我没有需要执行的操作,我只需要停止父线程的执行,直到子线程完成,这样就没有更多的子线程可以执行所述代码。锁定代码块不适用于公共静态只读变量,也不适用于与此最接近的是后台工作程序。但是你必须写几行。查看此链接了解更多详细信息:这也不起作用,因为在我的行动中,我需要自定义数据在事件arg中不可用。因为我了解您的情况,您使用任何此解决方案都不会有任何问题。若等待应该在UI上完成,只需禁用表单上的必需部分。如果wait应该在代码中完成,则在类中放置私有参数。有点像bool WorkingInProgress。作业开始时,设置WorkingInProgress=true。保留(使用while)任何其他进程,直到NotifyCompleteEvent交付事件。然后设置WorkingInProgress=false,并继续执行行中的下一个线程。