System.PlatformNotSupportedException:“Operation is not supported on this platform.”


vs2019創建.net core3.1 的控制台應用程序

執行以下代碼:

using System;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp3
{
    /// <summary>
    /// 委托必須和要調用的異步方法有相同的簽名
    /// </summary>
    /// <param name="callDuration">sleep時間</param>
    /// <param name="threadId">當前線程id</param>
    /// <returns></returns>
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    class Program
    {

        /// <summary>
        /// 主函數
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            AsyncMethodCaller caller = new AsyncMethodCaller(TestMethodAsync);
            int threadid = 0;
            //開啟異步操作
            IAsyncResult result = caller.BeginInvoke(3000, out threadid, null, null);
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("其它業務" + i.ToString());
            }
            //調用EndInvoke,等待異步執行完成
            Console.WriteLine("等待異步方法TestMethodAsync執行完成");
            string res = caller.EndInvoke(out threadid, result);
            Console.WriteLine("Completed!");
            Console.WriteLine(res);
            Console.Read();
        }
        /// <summary>
        /// 與委托對應的方法
        /// </summary>
        /// <param name="callDuration"></param>
        /// <param name="threadId"></param>
        /// <returns></returns>
        static string TestMethodAsync(int callDuration, out int threadId)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Console.WriteLine("異步TestMethodAsync開始");
            for (int i = 0; i < 5; i++)
            {   // 模擬耗時操作
                Thread.Sleep(callDuration);
                Console.WriteLine("TestMethodAsync:" + i.ToString());
            }
            sw.Stop();
            threadId = Thread.CurrentThread.ManagedThreadId;
            return string.Format("耗時{0}ms.", sw.ElapsedMilliseconds.ToString());
        }
    }
}

 

IAsyncResult result = caller.BeginInvoke(3000, out threadid, null, null);

所在行提示錯誤

 

 

System.PlatformNotSupportedException
  HResult=0x80131539
  Message=Operation is not supported on this platform.
  Source=ConsoleApp3
  StackTrace:
   at ConsoleApp3.AsyncMethodCaller.BeginInvoke(Int32 callDuration, Int32& threadId, AsyncCallback callback, Object object)
   at ConsoleApp3.Program.Main(String[] args) in C:\Users\pxm\source\repos\ConsoleApp3\ConsoleApp3\Program.cs:line 26

 

 

原因

The Asynchronous Programming Model (APM) (using IAsyncResult and BeginInvoke) is no longer the preferred method of making asynchronous calls. The Task-based Asynchronous Pattern (TAP) is the recommended async model as of .NET Framework 4.5. Because of this, and because the implementation of async delegates depends on remoting features not present in .NET Core, BeginInvoke and EndInvoke delegate calls are not supported in .NET Core. This is discussed in GitHub issue dotnet/corefx #5940.

異步編程模型(APM)(使用IAsyncResult和BeginInvoke)不再是異步調用的優選方法。從.NET Framework 4.5開始,基於任務的異步模式(TAP)是推薦的異步模型。因此,而且由於異步委托的實現取決於遠程處理但.NET Core不存在的功能,BeginInvoke和EndInvoke委托調用不.NET Core支持。GitHub問題 dotnet/corefx#5940 中對此進行了討論

Async delegates are not in .NET Core for several reasons:

  • Async delegates use deprecated IAsyncResult-based async pattern. This pattern is generally not supported throughout .NET Core base libraries, e.g. System.IO.Stream does not have IAsyncResult-based overloads for Read/Write methods in .NET Core.
  • Async delegates depend on remoting (System.Runtime.Remoting) under the hood. Remoting is not in .NET Core - implementation of async delegates without remoting would be challenging.

 

解決辦法

改為基於任務的異步模式Task.Run

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace ConsoleApp3
{
    /// <summary>
    /// 委托必須和要調用的異步方法有相同的簽名
    /// </summary>
    /// <param name="callDuration">sleep時間</param>
    /// <param name="threadId">當前線程id</param>
    /// <returns></returns>
    public delegate string AsyncMethodCaller(int callDuration, out int threadId);
    class Program
    {

        /// <summary>
        /// 主函數
        /// </summary>
        /// <param name="args"></param>
        static void Main(string[] args)
        {
            AsyncMethodCaller caller = new AsyncMethodCaller(TestMethodAsync);
            int threadid = 0;
            //開啟異步操作
            //IAsyncResult result = caller.BeginInvoke(3000, out threadid, null, null);
            var workTask = Task.Run(() => caller.Invoke(3000, out threadid));

            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine("其它業務" + i.ToString());
            }
            //調用EndInvoke,等待異步執行完成
            Console.WriteLine("等待異步方法TestMethodAsync執行完成");
            //string res = caller.EndInvoke(out threadid, result);
            string res = workTask.Result;

            Console.WriteLine("Completed!");
            Console.WriteLine(res);
            Console.Read();
        }
        /// <summary>
        /// 與委托對應的方法
        /// </summary>
        /// <param name="callDuration"></param>
        /// <param name="threadId"></param>
        /// <returns></returns>
        static string TestMethodAsync(int callDuration, out int threadId)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            Console.WriteLine("異步TestMethodAsync開始");
            for (int i = 0; i < 5; i++)
            {   // 模擬耗時操作
                Thread.Sleep(callDuration);
                Console.WriteLine("TestMethodAsync:" + i.ToString());
            }
            sw.Stop();
            threadId = Thread.CurrentThread.ManagedThreadId;
            return string.Format("耗時{0}ms.", sw.ElapsedMilliseconds.ToString());
        }
    }
}

 

參考:

1.Migrating Delegate.BeginInvoke Calls for .NET Core

2.初試WPF代碼遷移Core WPF

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM