从概念上讲,我想完成以下工作,但是在理解如何在C#中正确编写代码时遇到了麻烦:
1 2 3 4 5
| SomeMethod { // Member of AClass{}
DoSomething;
Start WorkerMethod() from BClass in another thread;
DoSomethingElse;
} |
然后,当WorkerMethod()完成时,运行以下命令:
1 2
| void SomeOtherMethod() // Also member of AClass{}
{ ... } |
有人可以举一个例子吗?
BackgroundWorker类已被添加到.NET 2.0中,用于此确切目的。
简而言之,您可以这样做:
1 2 3 4
| BackgroundWorker worker = new BackgroundWorker();
worker.DoWork += delegate { myBClass.DoHardWork(); }
worker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(SomeOtherMethod);
worker.RunWorkerAsync(); |
如果需要,您还可以添加一些精美的内容,例如取消和进度报告:)
在.Net 2中引入了BackgroundWorker,这使得运行异步操作非常容易:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| BackgroundWorker bw = new BackgroundWorker { WorkerReportsProgress = true };
bw.DoWork += (sender, e) =>
{
//what happens here must not touch the form
//as it's in a different thread
};
bw.ProgressChanged += ( sender, e ) =>
{
//update progress bars here
};
bw.RunWorkerCompleted += (sender, e) =>
{
//now you're back in the UI thread you can update the form
//remember to dispose of bw now
};
worker.RunWorkerAsync(); |
在.Net 1中,您必须使用线程。
尽管这里有多种可能性,但我将使用一个委托,该委托使用BeginInvoke方法异步调用。
警告:不要忘记总是在IAsyncResult上调用EndInvoke,以避免最终的内存泄漏,如本文所述。
您必须使用AsyncCallBacks。您可以使用AsyncCallBacks指定方法的委托,然后指定一旦目标方法执行完成就被调用的CallBack方法。
这是一个小示例,运行并亲自查看。
班级计划
{
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| 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();
}
} |
使用异步代理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| // 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 |
签出BackgroundWorker。
好吧,我不确定你想怎么做。从您的示例来看,WorkerMethod似乎没有创建要在其下执行的线程,但是您想在另一个线程上调用该方法。
在这种情况下,请创建一个简短的工作方法,该方法先调用WorkerMethod,然后再调用SomeOtherMethod,然后将该方法在另一个线程上排队。然后,当WorkerMethod完成时,将调用SomeOtherMethod。例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 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.
}
} |