将任务委派给任务,并在任务完成时得到通知(在C#中)

时间:2020-03-05 18:56:37  来源:igfitidea点击:

从概念上讲,我想完成以下工作,但在理解如何在C#中正确编写代码时遇到了麻烦:

SomeMethod { // Member of AClass{}
    DoSomething;
    Start WorkerMethod() from BClass in another thread;
    DoSomethingElse;
}

然后,当WorkerMethod()完成时,运行以下命令:

回答

好的,我不确定我们要如何处理。从示例来看,WorkerMethod似乎没有创建要在其下执行的线程,但是我们想在另一个线程上调用该方法。

在这种情况下,创建一个简短的工作方法,先调用WorkerMethod,然后再调用SomeOtherMethod,然后将该方法在另一个线程上排队。然后,当WorkerMethod完成时,将调用SomeOtherMethod。例如:

void SomeOtherMethod()  // Also member of AClass{}
{ ... }

Can anyone please give an example of that? 

Solution

Answer

Check out BackgroundWorker.

Answer

The BackgroundWorker class was added to .NET 2.0 for this exact purpose.

In a nutshell you do:

BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate { myBClass.DoHardWork(); }
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SomeOtherMethod);
worker.RunWorkerAsync();

回答

使用异步代表:

public class AClass
{
    public void SomeMethod()
    {
        DoSomething();

        ThreadPool.QueueUserWorkItem(delegate(object state)
        {
            BClass.WorkerMethod();
            SomeOtherMethod();
        });

        DoSomethingElse();
    }

    private void SomeOtherMethod()
    {
        // handle the fact that WorkerMethod has completed. 
        // Note that this is called on the Worker Thread, not
        // the main thread.
    }
}

回答

我们必须使用AsyncCallBacks。我们可以使用AsyncCallBacks指定方法的委托,然后指定一旦目标方法执行完成就被调用的CallBack方法。

这是一个小示例,运行并亲自查看。

班级计划
{

// Method that does the real work
public int SomeMethod(int someInput)
{
Thread.Sleep(20);
Console.WriteLine(”Processed input : {0}”,someInput);
return someInput+1;
} 

// Method that will be called after work is complete
public void EndSomeOtherMethod(IAsyncResult result)
{
SomeMethodDelegate myDelegate = result.AsyncState as SomeMethodDelegate;
// obtain the result
int resultVal = myDelegate.EndInvoke(result);
Console.WriteLine(”Returned output : {0}”,resultVal);
}

// Define a delegate
delegate int SomeMethodDelegate(int someInput);
SomeMethodDelegate someMethodDelegate = SomeMethod;

// Call the method that does the real work
// Give the method name that must be called once the work is completed.
someMethodDelegate.BeginInvoke(10, // Input parameter to SomeMethod()
EndSomeOtherMethod, // Callback Method
someMethodDelegate); // AsyncState

回答

在.Net 2中,引入了BackgroundWorker,这使得运行异步操作非常容易:

public delegate void AsyncMethodCaller();

    public static void WorkerMethod()
    {
        Console.WriteLine("I am the first method that is called.");
        Thread.Sleep(5000);
        Console.WriteLine("Exiting from WorkerMethod.");
    }

    public static void SomeOtherMethod(IAsyncResult result)
    {
        Console.WriteLine("I am called after the Worker Method completes.");
    }

    static void Main(string[] args)
    {
        AsyncMethodCaller asyncCaller = new AsyncMethodCaller(WorkerMethod);
        AsyncCallback callBack = new AsyncCallback(SomeOtherMethod);
        IAsyncResult result = asyncCaller.BeginInvoke(callBack, null);
        Console.WriteLine("Worker method has been called.");
        Console.WriteLine("Waiting for all invocations to complete.");
        Console.Read();

    }
}

在.Net 1中,我们必须使用线程。

回答

尽管这里有几种可能性,但我将使用一个委托,该委托使用BeginInvoke方法异步调用。

警告:不要忘记总是在IAsyncResult上调用EndInvoke,以避免最终的内存泄漏,如本文所述。

代码数量不匹配