cơ thể của các ChangedFileDumper, các thành viên gcroot dữ liệu được sử dụng như thể nó là của ^ FileSystemWatcher loại. Chú ý rằng tài sản Path là một tài sản của FileSystemWatcher, không phải là một tài sản của gcroot. Hành vi này có thể bởi vì gcroot | CHAPTER 9 MANAGED-UNMANAGED TRANSITIONS 225 As you can see in both tables calls across managed-unmanaged boundaries produced by C CLI can be more than 500 percent slower than calls without transitions. However unless you have a large number of transitions this overhead can likely be ignored. The difference in overhead between the 10 million calls to fManagedLocal from native callers and the 10 million calls from managed callers is about seconds. In addition to the measured time both tables also show the transitions that occur in the different scenarios. For example for the direct call to fManagedLocal from managed code the text M M shows that a call from managed code to managed code has occurred. Cells with the text U M indicate an unmanaged-to-managed transition. Likewise M U stands for a managed-to-unmanaged transition. For the indirect call to fManagedLocal from managed code the text M U M indicates a transition from managed code to unmanaged code and back to managed code. This is the double-thunking scenario discussed earlier. In addition to the double-thunking case Table 92 also shows the cost for an indirect method call with a_clrcall function pointer which can prevent double thunking as discussed earlier. As you can see double thunking can easily increase the costs for method calls by more than 600 percent. Table 9-3 shows similar results for the double-thunking problem related to virtual function calls. Optimizing Thunks For unmanaged-to-managed transitions there is no potential for improving the performance of the generated thunks. There are no hidden keywords or attributes that can be used for optimizations of transitions in this direction. An unmanaged-to-managed thunk has to perform certain expensive operations. For example it is possible that a managed function is called by a thread that has not yet executed managed code. The unmanaged-to-managed thunk must be prepared for that case so that a native thread will be automatically promoted