質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

1610閲覧

C#のStopWatchクラスが上手く実行されない。

shinya551

総合スコア11

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

0クリップ

投稿2017/11/30 08:49

###前提・実現したいこと

C#のStopWatchクラスを使って正確な時間を計測したい。

###発生している問題・エラーメッセージ

ペンタブレットの軌跡情報と一緒に時間も取りたくてStopWatchクラスを使用しました。

実行は出来るのですが、取得している時間が正しくありません。
1秒以上動作させても数ミリ秒程度しか出力されません。
実際に手動で時間を計測したところ2秒のものが4ミリ秒ほどになってしまっています。
以下は実行結果の一部です。カンマ区切りの一番左が時間です。

00:00:00.0000167,455,427,0

00:00:00.0004014,454,452,0

00:00:00.0004126,455,450,0

00:00:00.0004457,456,447,0

00:00:00.0004694,457,444,0

00:00:00.0005223,458,439,0

###該当のソースコード
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Interop;

using WintabNET;

namespace WpfWintabSample
{

/// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window {
//StopWacth呼び出し System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); //roop外でoldpress宣言 int oldpress = 0; // ウインドウプロシージャ private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) { if (msg == (int)EWintabEventMessage.WT_PACKET) { WintabPacket packet = WintabManager.GetPacket(lParam, (UInt32)wParam.ToInt32()); sw.Start();//StopWatch(再)スタート if (packet.pkNormalPressure.pkAbsolutePressure == 0) { Point screenPoint = PointToScreen(new Point(0, 0)); int x = (int)(packet.pkX - screenPoint.X); int y = (int)(packet.pkY - screenPoint.Y); //int t = sw.Elapsed; int p = (int)packet.pkNormalPressure.pkAbsolutePressure; sw.Stop();//StopWatchストップ if (x != (int)m_Point.X && y != (int)m_Point.Y /*&& oldpress == p*/) { //時間、座標、筆圧の書き出し(ペンUP) Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p); //screenText.Text += + sw.Elapsed + ","+ x + "," + y + "," + p + "\n"; //あとでtを追加 } //位置保存 m_Point.X = x; m_Point.Y = y; } else { Point screenPoint = PointToScreen(new Point(0, 0)); int x = (int)(packet.pkX - screenPoint.X); int y = (int)(packet.pkY - screenPoint.Y); int p = (int)packet.pkNormalPressure.pkAbsolutePressure; sw.Stop();//StopWatchストップ if (m_Point.X == -1) { m_Point.X = x; m_Point.Y = y; } else { if (x == (int)m_Point.X && y == (int)m_Point.Y && oldpress == p) { //線の追加 addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure); // 位置の保存 m_Point.X = x; m_Point.Y = y; oldpress = p; } else { //時間、座標、筆圧の書き出し(ペンDOWN) Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p); //screenText.Text += + sw.Elapsed + ","+ x + "," + y + "," + p + "\n";//あとでtを追加 //線の追加 addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure); // 位置の保存 m_Point.X = x; m_Point.Y = y; oldpress = p; } } } } return IntPtr.Zero; } // 線をCanvasに追加する private void addPath(int x, int y, int x2, int y2, int pressure) { Line l = new Line(); // 始点と終点の設定 l.X1 = x; l.Y1 = y; l.X2 = x2; l.Y2 = y2; // 線のスタイル設定 l.Stroke = Brushes.Black; l.StrokeStartLineCap = PenLineCap.Round; // 線の太さは筆圧によって変更する l.StrokeThickness = (double)pressure / (double)m_MaxPressure * 10.0; // Canvasへ線を追加 screenCanvas.Children.Add(l); } }

}

###試したこと
sw.ElapsedMillisecondsでミリ秒単位だけ取得しようとしましたが、
3秒以上実行しても6ミリ秒程しか進みません。

###補足情報(言語/FW/ツール等のバージョンなど)
僕のプログラムではなくネットの
WDN技術者(http://blog.wdnet.jp/tech/archives/156)さんのサンプルコードの
addpathというメソッドに直接書き込んでいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2017/11/30 09:10

コードは ``` と ``` で囲ってください。インデントされて見やすくなりますので。他人に見てもらおうと思うのならそのぐらいの心配りをお願いします。
guest

回答3

0

ベストアンサー

実際に計測したのはどの部分でしょうか?
現状のコードでは、StartとStop間に時間のかかりそうな部分もないため、正しい動作のようにも思えます。

動作タイミングを計測したいのであれば、Stopをかけずに出力でよいのでは?

投稿2017/11/30 11:42

mituha

総合スコア385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shinya551

2017/12/05 04:23

回答ありがとうございます。 インデント等見にくく申し訳ありませんでした。 ペンタブレットで入力している間の時間を計測して座標取得プログラムを1ループするたびにその時の時間を取り出そうと思っていたのですが、どうやらstopwatchクラスの使い方を間違えていたみたいでした。 結果的に一番最初のstartのすぐ上に2ループ目からstopをかけるようにして、if文の中のstopをかけたあとにすぐstartするようにすることで、継続的に時間を取ることが出来ました。 僕の力ではstopをかけずに値を取り出す方法が分からなかったため、ちょっと不格好ではありますがこれで時間計測をしていきたいと思います。 回答ありがとうございました。
guest

0

コメント返信だけでは言葉足らずな気がしたので一応コードも載せておきます。
”ずっと計測しつづけたい”とコメントアウトしているものが変更点です。
回答してくださった方はありがとうございました。

''' //StopWacth呼び出し ''' System.Diagnostics.Stopwatch sw = new System.Diagnostics.Stopwatch(); ''' ''' //roop外でoldpress宣言 ''' int oldpress = 0; ''' ''' //ずっと計測しつづけたい ''' int i = 0; ''' ''' // ウインドウプロシージャ ''' private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) ''' { ''' ''' if (msg == (int)EWintabEventMessage.WT_PACKET) ''' { ''' WintabPacket packet = WintabManager.GetPacket(lParam, (UInt32)wParam.ToInt32()); ''' ''' if (i >= 1) ''' { ''' sw.Stop();//ずっと計測しつづけたい ''' } ''' ''' sw.Start();//StopWatch(再)スタート ''' ''' if (packet.pkNormalPressure.pkAbsolutePressure == 0) ''' { ''' Point screenPoint = PointToScreen(new Point(0, 0)); ''' ''' int x = (int)(packet.pkX - screenPoint.X); ''' int y = (int)(packet.pkY - screenPoint.Y); ''' int p = (int)packet.pkNormalPressure.pkAbsolutePressure; ''' ''' sw.Stop();//StopWatchストップ ''' sw.Start();//ずっと計測しつづけたい ''' ''' long t = long sw.Elapsed; ''' ''' if (x != (int)m_Point.X && y != (int)m_Point.Y /*&& oldpress == p*/) ''' { ''' //時間、座標、筆圧の書き出し(ペンUP) ''' Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p); ''' } ''' //位置保存 ''' m_Point.X = x; ''' m_Point.Y = y; ''' ''' ''' } ''' else ''' { ''' Point screenPoint = PointToScreen(new Point(0, 0)); ''' ''' int x = (int)(packet.pkX - screenPoint.X); ''' int y = (int)(packet.pkY - screenPoint.Y); ''' int p = (int)packet.pkNormalPressure.pkAbsolutePressure; ''' ''' sw.Stop();//StopWatchストップ ''' sw.Start();//ずっと計測しつづけたい ''' ''' if (m_Point.X == -1) ''' { ''' m_Point.X = x; ''' m_Point.Y = y; ''' } ''' else ''' { ''' ''' if (x == (int)m_Point.X && y == (int)m_Point.Y && oldpress == p) ''' { ''' ''' //線の追加 ''' addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure); ''' ''' // 位置の保存 ''' m_Point.X = x; ''' m_Point.Y = y; ''' oldpress = p; ''' } ''' else ''' { ''' //時間、座標、筆圧の書き出し(ペンDOWN) ''' Console.WriteLine("{0},{1},{2},{3}\n", sw.Elapsed, x, y, p); ''' ''' //線の追加 ''' addPath((int)m_Point.X, (int)m_Point.Y, x, y, (int)packet.pkNormalPressure.pkAbsolutePressure); ''' ''' // 位置の保存 ''' m_Point.X = x; ''' m_Point.Y = y; ''' oldpress = p; ''' } ''' } ''' } ''' ''' i++;//ずっと計測しつづけたい ''' } ''' return IntPtr.Zero;

投稿2017/12/05 05:02

shinya551

総合スコア11

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

インデントがなくてよく分からないのですが、Stop後にもいろいろしているようなので、そこが遅いのではないでしょうか?

投稿2017/11/30 09:09

x_x

総合スコア13749

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shinya551

2017/12/05 04:27

回答ありがとうございます。 インデント等見にくく申し訳ありませんでした。 どうやら処理が遅かったのではなく、僕のstopのタイミングが悪いみたいでした。 mituhaさんへのコメントで書きましたがstopとstartを繋げることで、一応は解決いたしました。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問