當前位置: 首頁>>代碼示例>>C#>>正文


C# Overlapped.UnsafePack方法代碼示例

本文整理匯總了C#中System.Threading.Overlapped.UnsafePack方法的典型用法代碼示例。如果您正苦於以下問題:C# Overlapped.UnsafePack方法的具體用法?C# Overlapped.UnsafePack怎麽用?C# Overlapped.UnsafePack使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在System.Threading.Overlapped的用法示例。


在下文中一共展示了Overlapped.UnsafePack方法的15個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的C#代碼示例。

示例1: OverlappedCache

		internal unsafe OverlappedCache(Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast)
		{
			this.m_Overlapped = overlapped;
			this.m_PinnedObjects = pinnedObjects;
			this.m_PinnedObjectsArray = (alreadyTriedCast ? null : new object[0]);
			this.m_NativeOverlapped = new SafeNativeOverlapped((IntPtr)((void*)overlapped.UnsafePack(callback, pinnedObjects)));
		}
開發者ID:BjkGkh,項目名稱:R106,代碼行數:7,代碼來源:OverlappedCache.cs

示例2: CreateToken

        /// <summary>
        /// Creates a <see cref="CancellationTokenSource"/> for the given <paramref name="connectionId"/> and registers it for disconnect.
        /// </summary>
        /// <param name="connectionId">The connection id.</param>
        /// <returns>A <see cref="CancellationTokenSource"/> that is registered for disconnect for the connection associated with the <paramref name="connectionId"/>.</returns>
        public CancellationToken CreateToken(ulong connectionId)
        {
            Debug.WriteLine("Server: Registering connection for disconnect for connection ID: " + connectionId);
            // Create a nativeOverlapped callback so we can register for disconnect callback
            var overlapped = new Overlapped();
            var cts = new CancellationTokenSource();
            var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) =>
            {
                Debug.WriteLine("Server: http.sys disconnect callback fired for connection ID: " + connectionId);

                // Free the overlapped
                Overlapped.Free(pOVERLAP);

                // Pull the token out of the list and Cancel it.
                Lazy<CancellationToken> token;
                _connectionCancellationTokens.TryRemove(connectionId, out token);
                cts.Cancel();
            },
            null);

            uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

            if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                hr != NativeMethods.HttpErrors.NO_ERROR)
            {
                // We got an unknown result so throw
                Debug.WriteLine("Unable to register disconnect callback");
                return CancellationToken.None;
            }

            return cts.Token;
        }
開發者ID:Kazzje,項目名稱:SignalR,代碼行數:37,代碼來源:DisconnectHandler.cs

示例3: SetupOverlappedMultiple

        // Method to setup an Overlapped object with with multiple buffers pinned.        
        unsafe private void SetupOverlappedMultiple() {
            
            ArraySegment<byte>[] tempList = new ArraySegment<byte>[m_BufferList.Count];
            m_BufferList.CopyTo(tempList, 0);

            // Alloc new Overlapped.
            m_Overlapped = new Overlapped();

            // Number of things to pin is number of buffers.
            // Ensure we have properly sized object array.
            if(m_ObjectsToPin == null || (m_ObjectsToPin.Length != tempList.Length)) {
                m_ObjectsToPin = new object[tempList.Length];
            }

            // Fill in object array.
            for(int i = 0; i < (tempList.Length); i++) {
                m_ObjectsToPin[i] = tempList[i].Array;
            }

            if(m_WSABufferArray == null || m_WSABufferArray.Length != tempList.Length) {
                m_WSABufferArray = new WSABuffer[tempList.Length];
            }

            // Pin buffers and fill in WSABuffer descriptor pointers and lengths
#if SOCKETTHREADPOOL
            m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_ObjectsToPin));
#else
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_ObjectsToPin));
#endif
            for(int i = 0; i < tempList.Length; i++) {
                ArraySegment<byte> localCopy = tempList[i];
                ValidationHelper.ValidateSegment(localCopy);
                m_WSABufferArray[i].Pointer = Marshal.UnsafeAddrOfPinnedArrayElement(localCopy.Array, localCopy.Offset);
                m_WSABufferArray[i].Length = localCopy.Count;
            }
            m_PinState = PinState.MultipleBuffer;
        }
開發者ID:REALTOBIZ,項目名稱:mono,代碼行數:39,代碼來源:Socket.cs

示例4: SetupOverlappedSingle

        // Method to setup an Overlapped object with either m_Buffer or m_AcceptBuffer pinned.        
        unsafe private void SetupOverlappedSingle(bool pinSingleBuffer) {
            
            // Alloc new Overlapped.
            m_Overlapped = new Overlapped();

            // Pin buffer, get native pointers, and fill in WSABuffer descriptor.
            if(pinSingleBuffer) {
                if(m_Buffer != null) {
#if SOCKETTHREADPOOL
                    m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_Buffer));
#else
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_Buffer));
#endif
                    m_PinnedSingleBuffer = m_Buffer;
                    m_PinnedSingleBufferOffset = m_Offset;
                    m_PinnedSingleBufferCount = m_Count;
                    m_PtrSingleBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(m_Buffer, m_Offset);
                    m_PtrAcceptBuffer = IntPtr.Zero;
                    m_WSABuffer.Pointer = m_PtrSingleBuffer;
                    m_WSABuffer.Length = m_Count;
                    m_PinState = PinState.SingleBuffer;
                } else {
#if SOCKETTHREADPOOL
                    m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, null));
#else
                    m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, null));
#endif
                    m_PinnedSingleBuffer = null;
                    m_PinnedSingleBufferOffset = 0;
                    m_PinnedSingleBufferCount = 0;
                    m_PtrSingleBuffer = IntPtr.Zero;
                    m_PtrAcceptBuffer = IntPtr.Zero;
                    m_WSABuffer.Pointer = m_PtrSingleBuffer;
                    m_WSABuffer.Length = m_Count;
                    m_PinState = PinState.NoBuffer;
                }
            } else {
#if SOCKETTHREADPOOL
                m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
                m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_AcceptBuffer));
#else
                m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_AcceptBuffer));
#endif
                m_PinnedAcceptBuffer = m_AcceptBuffer;
                m_PtrAcceptBuffer = Marshal.UnsafeAddrOfPinnedArrayElement(m_AcceptBuffer, 0);
                m_PtrSingleBuffer = IntPtr.Zero;
                m_PinState = PinState.SingleAcceptBuffer;
            }
        }
開發者ID:REALTOBIZ,項目名稱:mono,代碼行數:52,代碼來源:Socket.cs

示例5: RegisterForDisconnect

        private void RegisterForDisconnect(HttpListenerContext context, Action disconnectCallback)
        {
            // Get the connection id value
            FieldInfo connectionIdField = typeof(HttpListenerRequest).GetField("m_ConnectionId", BindingFlags.Instance | BindingFlags.NonPublic);
            if (_requestQueueHandle != null && connectionIdField != null)
            {
                Debug.WriteLine("Server: Registering for disconnect");

                ulong connectionId = (ulong)connectionIdField.GetValue(context.Request);
                // Create a nativeOverlapped callback so we can register for disconnect callback
                var overlapped = new Overlapped();
                var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) =>
                {
                    Debug.WriteLine("Server: http.sys disconnect callback fired.");

                    // Free the overlapped
                    Overlapped.Free(pOVERLAP);

                    // Mark the client as disconnected
                    disconnectCallback();
                },
                null);

                uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

                if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                    hr != NativeMethods.HttpErrors.NO_ERROR)
                {
                    // We got an unknown result so throw
                    throw new InvalidOperationException("Unable to register disconnect callback");
                }
            }
            else
            {
                Debug.WriteLine("Server: Unable to resolve requestQueue handle. Disconnect notifications will be ignored");
            }
        }
開發者ID:nightbob3,項目名稱:SignalR,代碼行數:37,代碼來源:Server.cs

示例6: BeginRead

        internal unsafe IAsyncResult BeginRead(byte[] data, int offset, int size, AsyncCallback callback, object state)
        {
            PipeAsyncResult asyncResult = new PipeAsyncResult(callback);
            // Create a managed overlapped class
            // We will set the file offsets later
            Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, asyncResult);

            // Pack the Overlapped class, and store it in the async result
            NativeOverlapped* intOverlapped;
            intOverlapped = overlapped.UnsafePack(IOCallback, data);
            asyncResult._overlapped = intOverlapped;
            bool status;

            // pin the buffer and read data with overlapped
            fixed(byte* p = data) {
                    status = NativePipe.ReadFile(_handle, p + offset, size, IntPtr.Zero, intOverlapped);
            }
            if (!status)
            {
                int error = Marshal.GetLastWin32Error();
                // For pipes, when they hit EOF, they will come here.
                if (error == NativePipe.ERROR_BROKEN_PIPE) {
                    // Not an error, but EOF.  AsyncFSCallback will NOT be 
                    // called.  Call the user callback here.
                    asyncResult.CallUserCallback();                 
                    // EndRead will free the Overlapped struct correctly.
                }
                else if (error != NativePipe.ERROR_IO_PENDING)
                    throw new RemotingException(String.Format(CultureInfo.CurrentCulture, CoreChannel.GetResourceString("Remoting_Ipc_ReadFailure"), GetMessage(error)));
            }
            return asyncResult;
        }
開發者ID:nlh774,項目名稱:DotNetReferenceSource,代碼行數:32,代碼來源:IpcPort.cs

示例7: OverlappedIOCallback

 public unsafe OverlappedIOCallback(WaitCallback callback, ExceptionCallback exceptionCallback)
 {
     Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, null);
     this.nativeOverlapped = overlapped.UnsafePack(new IOCompletionThunk(this.IOCallback, exceptionCallback).ThunkFrame, null);
     this.callback = callback;
 }
開發者ID:Ruudvdl,項目名稱:SignalR.WindowsAzureServiceBus,代碼行數:6,代碼來源:SimpleIOThreadScheduler.cs

示例8: BeginWriteCore

 private unsafe FileStreamAsyncResult BeginWriteCore(byte[] bytes, int offset, int numBytes, AsyncCallback userCallback, object stateObject)
 {
     NativeOverlapped* overlappedPtr;
     FileStreamAsyncResult ar = new FileStreamAsyncResult {
         _handle = this._handle,
         _userCallback = userCallback,
         _userStateObject = stateObject,
         _isWrite = true
     };
     ManualResetEvent event2 = new ManualResetEvent(false);
     ar._waitHandle = event2;
     Overlapped overlapped = new Overlapped(0, 0, IntPtr.Zero, ar);
     if (userCallback != null)
     {
         overlappedPtr = overlapped.Pack(IOCallback, bytes);
     }
     else
     {
         overlappedPtr = overlapped.UnsafePack(null, bytes);
     }
     ar._overlapped = overlappedPtr;
     if (this.CanSeek)
     {
         long length = this.Length;
         if (this._exposedHandle)
         {
             this.VerifyOSHandlePosition();
         }
         if ((this._pos + numBytes) > length)
         {
             this.SetLengthCore(this._pos + numBytes);
         }
         overlappedPtr->OffsetLow = (int) this._pos;
         overlappedPtr->OffsetHigh = (int) (this._pos >> 0x20);
         this.SeekCore((long) numBytes, SeekOrigin.Current);
     }
     int hr = 0;
     if ((this.WriteFileNative(this._handle, bytes, offset, numBytes, overlappedPtr, out hr) == -1) && (numBytes != -1))
     {
         if (hr == 0xe8)
         {
             ar.CallUserCallback();
             return ar;
         }
         if (hr == 0x3e5)
         {
             return ar;
         }
         if (!this._handle.IsClosed && this.CanSeek)
         {
             this.SeekCore(0L, SeekOrigin.Current);
         }
         if (hr == 0x26)
         {
             __Error.EndOfFile();
             return ar;
         }
         __Error.WinIOError(hr, string.Empty);
     }
     return ar;
 }
開發者ID:pritesh-mandowara-sp,項目名稱:DecompliedDotNetLibraries,代碼行數:61,代碼來源:FileStream.cs

示例9: CreateToken

        private unsafe CancellationToken CreateToken(ulong connectionId)
        {
            // Create a nativeOverlapped callback so we can register for disconnect callback
            var overlapped = new Overlapped();
            var cts = new CancellationTokenSource();
            CancellationToken returnToken = cts.Token;

            NativeOverlapped* nativeOverlapped = overlapped.UnsafePack(
                (errorCode, numBytes, overlappedPtr) =>
                {
                    // Free the overlapped
                    Overlapped.Free(overlappedPtr);

                    if (errorCode != NativeMethods.HttpErrors.NO_ERROR)
                    {
                        LogHelper.LogException(_logger, "IOCompletionCallback", new Win32Exception((int)errorCode));
                    }

                    // Pull the token out of the list and Cancel it.
                    ConnectionCancellation cancellation;
                    _connectionCancellationTokens.TryRemove(connectionId, out cancellation);

                    bool success = ThreadPool.UnsafeQueueUserWorkItem(CancelToken, cts);
                    Debug.Assert(success, "Unable to queue disconnect notification.");
                },
                null);

            uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

            if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                hr != NativeMethods.HttpErrors.NO_ERROR)
            {
                // We got an unknown result, assume the connection has been closed.
                Overlapped.Free(nativeOverlapped);
                ConnectionCancellation cancellation;
                _connectionCancellationTokens.TryRemove(connectionId, out cancellation);
                LogHelper.LogException(_logger, "HttpWaitForDisconnect", new Win32Exception((int)hr));
                cts.Cancel();
                cts.Dispose();
            }

            return returnToken;
        }
開發者ID:Kstal,項目名稱:Microsoft.Owin,代碼行數:43,代碼來源:DisconnectHandler.cs

示例10: InitializeOverlapped

 private unsafe void InitializeOverlapped()
 {
     m_Overlapped = new Overlapped();
     m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, null));
 }
開發者ID:uQr,項目名稱:referencesource,代碼行數:5,代碼來源:WebSocketHttpListenerDuplexStream.cs

示例11: ReceiveLoop

        private void ReceiveLoop()
        {
            _listener.BeginGetContext(ar =>
            {
                HttpListenerContext context;
                try
                {
                    context = _listener.EndGetContext(ar);
                }
                catch (Exception)
                {
                    return;
                }

                var cts = new CancellationTokenSource();

                // Get the connection id value
                var connectionIdField = typeof(HttpListenerRequest).GetField("m_ConnectionId", BindingFlags.Instance | BindingFlags.NonPublic);
                if (_requestQueueHandle != null && connectionIdField != null)
                {
                    ulong connectionId = (ulong)connectionIdField.GetValue(context.Request);
                    // Create a nativeOverlapped callback so we can register for disconnect callback
                    var overlapped = new Overlapped();
                    var nativeOverlapped = overlapped.UnsafePack((errorCode, numBytes, pOVERLAP) =>
                    {
                        // Free the overlapped
                        Overlapped.Free(pOVERLAP);

                        // Mark the client as disconnected
                        cts.Cancel();
                    },
                    null);

                    uint hr = NativeMethods.HttpWaitForDisconnect(_requestQueueHandle, connectionId, nativeOverlapped);

                    if (hr != NativeMethods.HttpErrors.ERROR_IO_PENDING &&
                        hr != NativeMethods.HttpErrors.NO_ERROR)
                    {
                        // We got an unknown result so throw
                        throw new InvalidOperationException("Unable to register disconnect callback");
                    }
                }
                else
                {
                    Debug.WriteLine("Unable to resolve requestQueue handle. Disconnect notifications will be ignored");
                }

                ReceiveLoop();

                // Process the request async
                ProcessRequestAsync(context, cts.Token).ContinueWith(task =>
                {
                    if (task.IsFaulted)
                    {
                        Exception ex = task.Exception.GetBaseException();
                        context.Response.ServerError(ex).Catch();

                        Debug.WriteLine(ex.Message);
                    }

                    context.Response.CloseSafe();
                });

            }, null);
        }
開發者ID:ninjaAB,項目名稱:SignalR,代碼行數:65,代碼來源:Server.cs

示例12: DisconnectAsyncResult

 internal unsafe DisconnectAsyncResult(HttpListener httpListener, ulong connectionId) {
     GlobalLog.Print("DisconnectAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() httpListener#" + ValidationHelper.HashString(httpListener) + " connectionId:" + connectionId);
     m_OwnershipState = 1;
     m_HttpListener = httpListener;
     m_ConnectionId = connectionId;
     Overlapped overlapped = new Overlapped();
     overlapped.AsyncResult = this;
     // we can call the Unsafe API here, we won't ever call user code
     m_NativeOverlapped = overlapped.UnsafePack(s_IOCallback, null);
     GlobalLog.Print("DisconnectAsyncResult#" + ValidationHelper.HashString(this) + "::.ctor() overlapped#" + ValidationHelper.HashString(overlapped) + " nativeOverlapped:" + ((IntPtr)m_NativeOverlapped).ToString("x"));
 }
開發者ID:iskiselev,項目名稱:JSIL.NetFramework,代碼行數:11,代碼來源:HttpListener.cs

示例13: OverlappedCache

        internal OverlappedCache(Overlapped overlapped, object pinnedObjects, IOCompletionCallback callback, bool alreadyTriedCast)
        {
            m_Overlapped = overlapped;
            m_PinnedObjects = pinnedObjects;
            m_PinnedObjectsArray = alreadyTriedCast ? null : NclConstants.EmptyObjectArray;

            unsafe
            {
                m_NativeOverlapped = (IntPtr) overlapped.UnsafePack(callback, pinnedObjects);
            }
        }
開發者ID:gbarnett,項目名稱:shared-source-cli-2.0,代碼行數:11,代碼來源:_baseoverlappedasyncresult.cs

示例14: SetupOverlappedSendPackets

        // Method to setup an Overlapped object for SendPacketsAsync.        
        unsafe private void SetupOverlappedSendPackets() {

            int index;

            // Alloc new Overlapped.
            m_Overlapped = new Overlapped();

            // Alloc native descriptor.
            m_SendPacketsDescriptor = 
                new UnsafeNclNativeMethods.OSSOCK.TransmitPacketsElement[m_SendPacketsElementsFileCount + m_SendPacketsElementsBufferCount];

            // Number of things to pin is number of buffers + 1 (native descriptor).
            // Ensure we have properly sized object array.
            if(m_ObjectsToPin == null || (m_ObjectsToPin.Length != m_SendPacketsElementsBufferCount + 1)) {
                m_ObjectsToPin = new object[m_SendPacketsElementsBufferCount + 1];
            }

            // Fill in objects to pin array. Native descriptor buffer first and then user specified buffers.
            m_ObjectsToPin[0] = m_SendPacketsDescriptor;
            index = 1;
            foreach(SendPacketsElement spe in m_SendPacketsElementsInternal) {                
                if(spe != null && spe.m_Buffer != null && spe.m_Count > 0) {
                    m_ObjectsToPin[index] = spe.m_Buffer;
                    index++;
                }
            }

            // Pin buffers
#if SOCKETTHREADPOOL
            m_Overlapped.AsyncResult = new DummyAsyncResult(CompletionPortCallback);
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(null, m_ObjectsToPin));
#else
            m_PtrNativeOverlapped = new SafeNativeOverlapped(m_Overlapped.UnsafePack(CompletionPortCallback, m_ObjectsToPin));
#endif

            // Get pointer to native descriptor.
            m_PtrSendPacketsDescriptor = Marshal.UnsafeAddrOfPinnedArrayElement(m_SendPacketsDescriptor, 0);
            
            // Fill in native descriptor.
            int descriptorIndex = 0;
            int fileIndex = 0;
            foreach(SendPacketsElement spe in m_SendPacketsElementsInternal) {
                if (spe != null) {
                    if(spe.m_Buffer != null && spe.m_Count > 0) {
                        // a buffer
                        m_SendPacketsDescriptor[descriptorIndex].buffer = Marshal.UnsafeAddrOfPinnedArrayElement(spe.m_Buffer, spe.m_Offset);
                        m_SendPacketsDescriptor[descriptorIndex].length = (uint)spe.m_Count;
                        m_SendPacketsDescriptor[descriptorIndex].flags = spe.m_Flags;
                        descriptorIndex++;
                    } else if (spe.m_FilePath != null) {
                        // a file
                        m_SendPacketsDescriptor[descriptorIndex].fileHandle = m_SendPacketsFileHandles[fileIndex].DangerousGetHandle();
                        m_SendPacketsDescriptor[descriptorIndex].fileOffset = spe.m_Offset;
                        m_SendPacketsDescriptor[descriptorIndex].length = (uint)spe.m_Count;
                        m_SendPacketsDescriptor[descriptorIndex].flags = spe.m_Flags;
                        fileIndex++;
                        descriptorIndex++;
                    }
                }
            }

            m_PinState = PinState.SendPackets;
        }
開發者ID:REALTOBIZ,項目名稱:mono,代碼行數:64,代碼來源:Socket.cs

示例15: AsyncJob

		/// <summary>
		/// Create instance, automatically allocates NativeOverlapped structure
		/// </summary>
		/// <param name="callback">User specified callback</param>
		/// <param name="state">User specified state</param>
		/// <param name="fileOffset">Start position</param>
		/// <param name="userData">An object or array of objects representing the input or output buffer for the operation. Buffer is pinned until object is disposed.</param>
		public AsyncJob(AsyncCallback callback, object state, UInt64 fileOffset, object userData) {
			_callback = callback;
			_state = state;
			Overlapped ov = new Overlapped(unchecked((int)(fileOffset & 0xFFFFFFFF)), unchecked((int)((fileOffset >> 32) & 0xFFFFFFFF)), IntPtr.Zero, this);
			unsafe { _nativeOverlapped = ov.UnsafePack(completionCallback, userData); }
		}
開發者ID:Gainedge,項目名稱:BetterExplorer,代碼行數:13,代碼來源:AsyncJob.cs


注:本文中的System.Threading.Overlapped.UnsafePack方法示例由純淨天空整理自Github/MSDocs等開源代碼及文檔管理平台,相關代碼片段篩選自各路編程大神貢獻的開源項目,源碼版權歸原作者所有,傳播和使用請參考對應項目的License;未經允許,請勿轉載。