猿问

如何作为共享库异步返回函数的进度

所以我想使用下面的方法在 golang 中创建一个下载文件的函数,我将这个 golang 项目构建到 C .dll 中使用


go build -buildmode=c-shared -o patcher.dll main.go

我设法在我的 C# 应用程序上使用这个函数来获取文件下载的进度,如果我只是使用 DownloadFile() 直接打印它,我当前的函数 (DownloadFfile) 就可以工作,但是我想在我的 C# 应用程序上异步获取进度,但是我无法直接获取值,所以我想我需要从我的 golang 应用程序返回进度的整数,但如果我这样做,函数只执行 1 次(进度的最后结果)


问题是如何让我的 go func DownloadFile 在我的 C# 应用程序上被调用 1 次,但我仍然可以跟踪进度?任何帮助将不胜感激,谢谢。


func DownloadFile(){

    // create client

    client := grab.NewClient()

    req, _ := grab.NewRequest(".", "http://www.golang-book.com/public/pdf/gobook.pdf")


    // start download

    fmt.Printf("Downloading %v...\n", req.URL())

    resp := client.Do(req)

    fmt.Printf("  %v\n", resp.HTTPResponse.Status)


    // start UI loop

    t := time.NewTicker(500 * time.Millisecond)

    defer t.Stop()


Loop:

    for {

        select {

        case <-t.C:

            fmt.Printf("%.2f%",

                //resp.BytesComplete(),

                //resp.Size,

                100*resp.Progress())


        case <-resp.Done:

            // download is complete

            break Loop

        }

    }


    // check for errors

    if err := resp.Err(); err != nil {

        fmt.Fprintf(os.Stderr, "Download failed: %v\n", err)

        os.Exit(1)

    }


    // fmt.Printf("Download saved to ./%v \n", resp.Filename)


    // Output:

    // Downloading http://www.golang-book.com/public/pdf/gobook.pdf...

    //   200 OK

    //   transferred 42970 / 2893557 bytes (1.49%)

    //   transferred 1207474 / 2893557 bytes (41.73%)

    //   transferred 2758210 / 2893557 bytes (95.32%)

    // Download saved to ./gobook.pdf

}


梦里花落0921
浏览 100回答 1
1回答

斯蒂芬大帝

所以,在谷歌搜索之后,我找到了答案,我需要像下面这样在Go上使 setter 和 getter “类似” 。var Progress intvar DownloadSpeed int//export DownloadFilefunc DownloadFile(){&nbsp; &nbsp; // create client&nbsp; &nbsp; client := grab.NewClient()&nbsp; &nbsp; req, _ := grab.NewRequest(".", "https://upload.wikimedia.org/wikipedia/commons/d/d6/Wp-w4-big.jpg")&nbsp; &nbsp; // start download&nbsp; &nbsp; fmt.Printf("Downloading %v...\n", req.URL())&nbsp; &nbsp; resp := client.Do(req)&nbsp; &nbsp; fmt.Printf("&nbsp; %v\n", resp.HTTPResponse.Status)&nbsp; &nbsp; // start UI loop&nbsp; &nbsp; t := time.NewTicker(500 * time.Millisecond)&nbsp; &nbsp; defer t.Stop()Loop:&nbsp; &nbsp; for {&nbsp; &nbsp; &nbsp; &nbsp; select {&nbsp; &nbsp; &nbsp; &nbsp; case <-t.C:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //progress = 100*(resp.Progress())&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetProgressValue(int(resp.Progress() * 100))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetDownloadSpeedValue(int(resp.BytesPerSecond()))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //fmt.Println(progress)&nbsp; &nbsp; &nbsp; &nbsp; case <-resp.Done:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // download is complete&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; SetProgressValue(100)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //fmt.Println(Progress)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break Loop&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; // check for errors&nbsp; &nbsp; if err := resp.Err(); err != nil {&nbsp; &nbsp; &nbsp; &nbsp; fmt.Fprintf(os.Stderr, "Download failed: %v\n", err)&nbsp; &nbsp; &nbsp; &nbsp; os.Exit(1)&nbsp; &nbsp; }&nbsp; &nbsp; fmt.Printf("Download saved to ./%v \n", resp.Filename)&nbsp; &nbsp; fmt.Println("Completed")}//export ProgressValuefunc ProgressValue() int {&nbsp; &nbsp; return Progress}//export SetProgressValuefunc SetProgressValue(val int) {&nbsp; &nbsp; Progress = val}然后在C#中使用:&nbsp;void worker_DoWork(object sender, DoWorkEventArgs e) {&nbsp; &nbsp; [DllImport(@"M:\GolangProjects\PatcherDLL\patcher.dll", EntryPoint = "ProgressValue")]&nbsp; &nbsp; &nbsp;static extern int ProgressValue();&nbsp; &nbsp; public partial class MainWindow : Window {&nbsp; &nbsp; var task = Task.Factory.StartNew(() => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; DownloadFile();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while (!task.IsCompleted)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Thread.Sleep(100);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; string downloadSpeedFormatted = "";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (DownloadSpeedValue()/1000 > 999)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; downloadSpeedFormatted = Math.Round((double) DownloadSpeedValue() / 1000000, 2) + " MB/s";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; downloadSpeedFormatted = DownloadSpeedValue() / 1000 + " kb/s";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Dispatcher.BeginInvoke(new Action(delegate {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; progressbar1.Value = ProgressValue();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; progressPercent1.Text = ProgressValue() + "%";&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; downloadSpeeds.Content = downloadSpeedFormatted;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}
随时随地看视频慕课网APP

相关分类

Go
我要回答